Con Unity, ¿cómo inyectaré una dependencia con nombre en un constructor?

Tengo el IRespository registrado dos veces (con nombres) en el siguiente código:

// Setup the Client Repository IOC.Container.RegisterType(new InjectionConstructor()); IOC.Container.RegisterType ("Client", new InjectionConstructor(typeof(ClientEntities))); // Setup the Customer Repository IOC.Container.RegisterType(new InjectionConstructor()); IOC.Container.RegisterType ("Customer", new InjectionConstructor(typeof(CustomerEntities))); IOC.Container.RegisterType(); IOC.Container.RegisterType(); 

Pero cuando quiero resolver esto (para usar el IRepository) tengo que hacer una resolución manual como esta:

 public ClientModel(IUnityContainer container) { this.dataAccess = container.Resolve(Client); ..... } 

Lo que me gustaría hacer es resolverlo en el constructor (al igual que IUnityContainer). Necesito alguna forma de decir qué tipo de nombre resolver.

Algo como esto: (NOTA: Código no real)

 public ClientModel([NamedDependancy("Client")] IRepository dataAccess) { this.dataAccess = dataAccess; ..... } 

¿Hay alguna manera de hacer que mi código falso funcione?

Puede configurar dependencias con o sin nombres en la API, los atributos o mediante el archivo de configuración. No mencionó XML arriba, así que supongo que está usando la API.

Para decirle al contenedor que resuelva una dependencia con nombre, deberá usar un objeto InjectionParameter. Para su ejemplo de ClientModel, haga esto:

 container.RegisterType( new InjectionConstructor( // Explicitly specify a constructor new ResolvedParameter("Client") // Resolve parameter of type IRepository using name "Client" ) ); 

Esto le dice al contenedor “Al resolver ClientModel, llame al constructor que toma un solo parámetro IRepository. Al resolver ese parámetro, resuelva con el nombre ‘Cliente’ además del tipo.”

Si quería usar atributos, su ejemplo casi funciona, solo necesita cambiar el nombre del atributo:

 public ClientModel([Dependency("Client")] IRepository dataAccess) { this.dataAccess = dataAccess; ..... } 

Esta es una respuesta muy tardía, pero la pregunta aún aparece en Google.

Entonces de todos modos, 5 años después …

Tengo un enfoque bastante simple. Por lo general, cuando necesita usar “dependencia nombrada” es porque está tratando de implementar algún tipo de patrón de estrategia. En ese caso, simplemente creo un nivel de indirección entre Unity y el rest de mi código llamado StrategyResolver para que no dependa directamente de Unity.

 public class StrategyResolver : IStrategyResolver { private IUnityContainer container; public StrategyResolver(IUnityContainer unityContainer) { this.container = unityContainer; } public T Resolve(string namedStrategy) { return this.container.Resolve(namedStrategy); } } 

Uso:

 public class SomeClass: ISomeInterface { private IStrategyResolver strategyResolver; public SomeClass(IStrategyResolver stratResolver) { this.strategyResolver = stratResolver; } public void Process(SomeDto dto) { IActionHandler actionHanlder = this.strategyResolver.Resolve(dto.SomeProperty); actionHanlder.Handle(dto); } } 

Registro:

 container.RegisterType("One"); container.RegisterType("Two"); container.RegisterType(); container.RegisterType(); 

Ahora, lo bueno de esto es que nunca más tendré que volver a tocar StrategyResolver cuando agregue nuevas estrategias en el futuro.

Es muy sencillo. Muy limpio y mantuve la dependencia en Unity a un mínimo estricto. La única vez que habría tocado el StrategyResolver es si decido cambiar la tecnología del contenedor, que es muy poco probable que suceda.

¡Espero que esto ayude!

Editar: realmente no me gusta la respuesta aceptada porque cuando usas el atributo Dependency en el constructor de tu servicio, en realidad tienes una dependencia fuerte en Unity. El atributo Dependency es parte de la biblioteca de Unity. En ese punto, también podría pasar una dependencia IUnityContainer todas partes.

Prefiero que mis clases de servicio dependan de objetos que poseo por completo en lugar de tener una dependencia dura de una biblioteca externa en todas partes. Además, el uso del atributo Dependency hace que las firmas de los constructores sean menos limpias y simples.

Además, esta técnica permite resolver dependencias nombradas en tiempo de ejecución sin tener que codificar las dependencias nombradas en el constructor, en el archivo de configuración de la aplicación o usar InjectionParameter que son todos los métodos que requieren saber qué dependencia nombrada usar en el momento del diseño.

Editar (2016-09-19): para aquellos que se preguntan, el contenedor sabrá que se pasa cuando se solicita IUnityContainer como dependencia, como se muestra en la firma del constructor StrategyResolver .

Debería poder usar ParameterOverrides

 var repository = IOC.Container.Resolve("Client"); var clientModel = IOC.Container.Resolve(new ParameterOverrides { {"dataAccess", repository } } ); 

edit: no estoy seguro de por qué estás pasando por el UnityContainer: personalmente, inyectamos nuestras dependencias en el propio constructor (que es “normal” por lo que he visto). Pero independientemente, puede especificar un nombre en sus métodos RegisterType y Resolve.

 IOC.Container.RegisterType("Client"); IOC.Container.Resolve("Client"); 

y le dará el tipo que registró para ese nombre.

No hagas esto: simplemente crea una class ClientRepository : GenericRepository { } y utiliza el sistema Type.