2011-11-15 27 views
5

Tôi đang cố gắng áp dụng tính năng hỗ trợ trang trí tự động cho kịch bản của mình mà không thành công. Có vẻ như trong trường hợp của tôi, nó không gán tên cho đăng ký đúng cách.Autofac trang trí các generics mở được đăng ký sử dụng chức năng quét lắp ráp

Có cách nào để đăng ký loại lắp ráp được quét với tên không, để sau này tôi có thể sử dụng nó trong khóa trang trí chung mở?

Hoặc có thể tôi hoàn toàn sai và đang làm điều gì đó không phù hợp ở đây?

builder.RegisterAssemblyTypes(typeof(IAggregateRepositoryAssembly).Assembly) 
    .AsClosedTypesOf(typeof(IAggregateViewRepository<>)) //here I need name, probably 
    .Named("view-implementor", typeof(IAggregateViewRepository<>)) 
    .SingleInstance(); 

builder.RegisterGenericDecorator(typeof(CachedAggregateViewRepository<>), 
    typeof(IAggregateViewRepository<>), fromKey: "view-implementor"); 

Trả lời

13

Dưới đây là một nỗ lực, chứ không phải ở phía trước của Visual Studio để giải quyết tình trạng quá tải có thể không được chính xác đúng:

builder.RegisterAssemblyTypes(typeof(IAggregateRepositoryAssembly).Assembly) 
    .As(t => t.GetInterfaces() 
       .Where(i => i.IsClosedTypeOf(typeof(IAggregateViewRepository<>)) 
       .Select(i => new KeyedService("view-implementor", i)) 
       .Cast<Service>()) 
    .SingleInstance(); 
  • Named() là đường chỉ là cú pháp cho Keyed(), mà liên kết các thành phần với một KeyedService
  • As() chấp nhận một Func<Type, IEnumerable<Service>>

Bạn cũng sẽ cần:

using Autofac; 
using Autofac.Core; 
+0

trình như một say mê! Cảm ơn rất nhiều! – achekh

+0

Tuyệt vời! Vui mừng khi nghe nó. –

+1

Điều này cũng phù hợp với tôi. Tôi không tin rằng Cast () là cần thiết, tuy nhiên. – luksan

2

Nếu bạn muốn dọn dẹp mã số đăng ký của bạn, bạn cũng có thể xác định các phương pháp khuyến nông bổ sung sau đây (rất dài dòng và dựa trên các nguồn autofac cho tình trạng quá tải khác, nhưng nó chỉ cần phải được định nghĩa một lần):

using Autofac; 
using Autofac.Builder; 
using Autofac.Core; 
using Autofac.Features.Scanning; 

public static class AutoFacExtensions 
{ 
    public static IRegistrationBuilder<TLimit, TScanningActivatorData, TRegistrationStyle> 
     AsClosedTypesOf<TLimit, TScanningActivatorData, TRegistrationStyle>(
      this IRegistrationBuilder<TLimit, TScanningActivatorData, TRegistrationStyle> registration, 
      Type openGenericServiceType, 
      object key) 
     where TScanningActivatorData : ScanningActivatorData 
    { 
     if (openGenericServiceType == null) throw new ArgumentNullException("openGenericServiceType"); 

     return registration.As(t => 
      new[] { t } 
      .Concat(t.GetInterfaces()) 
      .Where(i => i.IsClosedTypeOf(openGenericServiceType)) 
      .Select(i => new KeyedService(key, i))); 
    } 
} 

Điều đó sẽ cho phép bạn chỉ cần làm điều này:

builder.RegisterAssemblyTypes(typeof(IAggregateRepositoryAssembly).Assembly) 
    .AsClosedTypesOf(typeof(IAggregateViewRepository<>), "view-implementor") 
    .SingleInstance(); 
Các vấn đề liên quan