2013-07-09 11 views
6

Ho un ICallHandler che desidero registrare con tutte le istanze del contenitore Unity.Registrazione stessa intercettazione Unity e gestore di chiamata per tutti i tipi registrati

Per esempio, prendete il seguente gestore:

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

E il seguente costruttore contenitore CIO:

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

Tutto quello che voglio fare è registrare il gestore con tutti questi tipi.

posso fare questo w/un codice abbastanza verbose:

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

Ma non solo devo scrivere lo stesso codice di intercettazione su tutte le mie tipo immatricolazioni (immaginate se ho più di 100 registrazioni di tipo) , ma devo anche includere uno HandlerAttribute su ogni interfaccia (di nuovo, non va bene se ho più di 100 interfacce per applicare questo a).

Questa è la mia unica opzione, oppure esiste un modo per farlo a livello di contenitore per evitare di doverlo applicare a ogni singola interfaccia di tipo registrazione &?

risposta

9

Unità 3 fornisce registration by convention che potrebbe aiutare in questo scenario:

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

è possibile combinare quanto sopra con Policy Injection utilizzare le regole di corrispondenza per cablare il vostro gestore di chiamata. In questo modo è possibile utilizzare una varietà di regole di corrispondenza anziché (o in combinazione con) attributi per determinare quali gestori di chiamate vanno con quali classi/metodi.

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 supporta anche Policy Injection.

Un'alternativa alla registrazione per convenzione sarebbe quella di scrivere un'estensione Contenitore Unity per eseguire il cablaggio dell'intercettazione durante la registrazione.

+0

Grazie Tuzo. Siamo su .NET 4.0, quindi sono limitati a Unity 2.0. Prima di pubblicare, ho provato a farlo funzionare utilizzando Policy Injection, ma non riuscivo a farlo funzionare. Ne esaminerò ancora un po 'e, se non riuscirò a farlo funzionare con Policy Injection, aggiornerò il post originale con quello che ho. –

Problemi correlati