2013-07-09 8 views
6

Mam ICallHandler, który chcę zarejestrować we wszystkich instancjach kontenera Unity.Zarejestruj to samo przechwytywanie Unity i program obsługi połączeń dla wszystkich zarejestrowanych typów.

Na przykład, weźmy następujące Handler:

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; 
    } 
} 

i następujące konstruktora kontenera IoC:

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

Wszystko co chcę zrobić, to zarejestrować ten moduł obsługi ze wszystkich tych typów.

mogę to zrobić w/jakiś dość gadatliwym kodu:

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()); 
    } 
} 

Ale nie tylko muszę pisać tego samego kodu przechwytywania na wszystkie moje rejestracje typu (wyobraźcie sobie, że mam ponad 100 typów rejestracje) , ale muszę też dodać HandlerAttribute na każdym interfejsie (znowu nie jest dobrze, jeśli mam ponad 100 interfejsów, żeby to zastosować).

Czy jest to moja jedyna opcja, czy istnieje sposób, aby to zrobić na poziomie kontenera, aby uniknąć konieczności stosowania tego do każdego indywidualnego interfejsu rejestracji typu &?

Odpowiedz

9

Unity 3 zapewnia registration by convention które mogłyby pomóc w tym scenariuszu:

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>() 
    }); 
} 

Można połączyć powyżej Policy Injection użyć dopasowania reguł do drutu swój obsługi połączeń. W ten sposób można użyć różnych reguł dopasowania zamiast atrybutów (lub w połączeniu z), aby określić, które procedury obsługi wywołaj z którymi klasami/metodami.

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 obsługuje również wtrysk polityki.

Alternatywą dla rejestracji przez konwencję byłoby napisanie rozszerzenia Unity Container w celu przeprowadzenia okablowania przechwycenia podczas rejestracji.

+0

Dzięki Tuzo. Jesteśmy na .NET 4.0, więc jesteśmy ograniczeni do Unity 2.0. Przed opublikowaniem próbowałem uruchomić to za pomocą wtrysku zasad, ale nie mogłem go uruchomić. Zajmę się tym jeszcze trochę i jeśli nie będę w stanie tego zrobić z wtryskiem polityki, zaktualizuję oryginalny post z tym, co mam. –

Powiązane problemy