2013-07-09 31 views
6

Tôi có một ICallHandler mà tôi muốn đăng ký với tất cả các phiên bản vùng chứa Unity của tôi.Đăng ký cùng chức năng chặn và xử lý cuộc gọi Unity cho tất cả các loại đăng ký

Ví dụ, hãy xử lý như sau:

public class ProfilerHandler : ICallHandler 
{ 
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) 
    { 
     //start timer 
     IMethodReturn methodReturn = getNext()(input, getNext); 
     //stop timer 
    } 

    public int Order 
    { 
     get; set; 
    } 
} 

Và constructor container IoC sau:

public class IoCContainer : UnityContainer 
{ 
    public IoCContainer() 
    { 
     this.RegisterType<IUserService, UserService>(new ContainerControlledLifetimeManager()); 
     this.RegisterType<IRepository<User>, UserRepository>(new ContainerControlledLifetimeManager()); 
    } 
} 

Tất cả tôi muốn làm là đăng ký xử lý này với tất cả các loại.

tôi có thể làm điều này w/một số mã khá dài dòng:

public class IoCContainer : UnityContainer 
{ 
    public IoCContainer() 
    { 
     this.AddNewExtension<Interception>(); 

     this.RegisterType<IUserService, UserService>(new ContainerControlledLifetimeManager()).Configure<Interception>().SetInterceptorFor<IUserService>(new InterfaceInterceptor()); 
     this.RegisterType<IRepository<User>, UserRepository>(new ContainerControlledLifetimeManager()).Configure<Interception>().SetInterceptorFor<IRepository<User>>(new InterfaceInterceptor()); 
    } 
} 

Nhưng không chỉ làm tôi phải viết mã chặn nhau trên tất cả các đăng ký kiểu của tôi (hãy tưởng tượng nếu tôi có 100 đăng ký loại) , nhưng tôi cũng phải bao gồm một HandlerAttribute trên mọi giao diện (một lần nữa, không tốt nếu tôi có hơn 100 giao diện để áp dụng điều này).

Đây có phải là lựa chọn duy nhất của tôi hoặc có cách để thực hiện việc này ở cấp vùng chứa để tránh phải áp dụng điều này cho từng loại đăng ký riêng lẻ & giao diện không?

Trả lời

9

Unity 3 cung cấp registration by convention mà có thể giúp đỡ trong tình huống này:

IUnityContainer container = new UnityContainer(); 

container.AddNewExtension<Interception>(); 

container.RegisterTypes(
    AllClasses.FromLoadedAssemblies().Where(
     t => t.Namespace == "My.Namespace.Services"), 
    WithMappings.MatchingInterface, 
    getInjectionMembers: t => new InjectionMember[] 
    { 
     new Interceptor<InterfaceInterceptor>(), 
     new InterceptionBehavior<MyBehavior>() 
    }); 
} 

Bạn có thể kết hợp trên với Policy Injection sử dụng quy tắc phù hợp để dây lên xử lý cuộc gọi của bạn. Bằng cách đó bạn có thể sử dụng một loạt các quy tắc phù hợp thay vì (hoặc kết hợp với) các thuộc tính để xác định trình xử lý cuộc gọi nào đi với các lớp/phương thức nào.

container.RegisterTypes(
    AllClasses.FromLoadedAssemblies().Where(
     t => t.Namespace == "My.Namespace.Services"), 
    WithMappings.MatchingInterface, 
    getInjectionMembers: t => new InjectionMember[] 
    { 
     new InterceptionBehavior<PolicyInjectionBehavior>(), 
     new Interceptor<InterfaceInterceptor>(), 
    }); 
} 

container.Configure<Interception>() 
    .AddPolicy("profiler") 
    .AddMatchingRule<AssemblyMatchingRule>(
     new InjectionConstructor(
      new InjectionParameter("My.Namespace.Services"))) 
    .AddCallHandler<ProfilerHandler>(
     new ContainerControlledLifetimeManager()); 

Unity 2 cũng hỗ trợ chính sách Injection.

Một cách thay thế cho việc đăng ký theo quy ước sẽ là viết một Tiện ích mở rộng Container Thống nhất để thực hiện việc đấu dây trong khi đăng ký.

+0

Cảm ơn Tuzo. Chúng tôi đang trên .NET 4.0, do đó, được giới hạn trong Unity 2.0. Trước khi đăng bài, tôi đã cố gắng để làm việc này bằng cách sử dụng chính sách Injection, nhưng không thể làm cho nó hoạt động. Tôi sẽ xem xét nó một số chi tiết, và nếu tôi không thể làm cho nó hoạt động w/Chính sách Injection, sẽ cập nhật các bài gốc w/những gì tôi có. –

Các vấn đề liên quan