Estoy usando Unity de Microsoft para la inyección de dependencia y quiero hacer algo como esto:
IDataContext context = _unityContainer.Resolve<IDataContext>();
var repositoryA = _unityContainer.Resolve<IRepositoryA>(context); //Same instance of context
var repositoryB = _unityContainer.Resolve<IRepositoryB>(context); //Same instance of context
IDataContext context2 = _unityContainer.Resolve<IDataContext>(); //New instance
var repositoryA2 = _unityContainer.Resolve<IRepositoryA>(context2);
RepositoryA
y RepositoryB
ambos tienen un constructor que toma un IDataContext
parámetro, y quiero que Unity inicialice el repositorio con el contexto que le paso. También tenga en cuenta que IDataContext
no está registrado con Unity (no quiero 3 instancias de IDataContext
).
Foo(string name, int address) { ... }
container.Resolve<IFoo>(new ParameterOverrides { { "name", "bar" }, { "address", 42 } });
<2 centavos>
¿Qué pasa si más adelante decide utilizar un servicio diferente que requiere más o menos que solo el contexto?
El problema con los parámetros del constructor y el IoC es que, en última instancia, los parámetros están vinculados al tipo concreto que se utiliza, en lugar de formar parte del contrato que define la interfaz de servicio.
Mi sugerencia sería que resuelva el contexto también, y creo que Unity debería tener una forma de evitar la construcción de 3 instancias de él, o debería considerar un servicio de fábrica que tenga una forma de construir el objeto.
Por ejemplo, ¿qué pasa si más adelante decide construir un repositorio que no dependa en absoluto de una base de datos tradicional, sino que utilice un archivo XML para producir datos ficticios para la prueba? ¿Cómo haría para alimentar el contenido XML a ese constructor?
IoC se basa en el código de desacoplamiento, al vincular el tipo y la semántica de los argumentos a los tipos concretos, realmente no ha realizado el desacoplamiento correctamente, todavía hay una dependencia.
"Este código puede comunicarse con cualquier tipo de repositorio posiblemente, siempre que implemente esta interfaz ... Ah, y use un contexto de datos".
Ahora, sé que otros contenedores de IoC tienen soporte para esto, y también lo tenía en mi primera versión, pero en mi opinión, no pertenece al paso de resolución.
</ 2 centavos>
fuente
Gracias chicos ... el mío es similar al post de "Exist". Vea abajo:
fuente
Puede usar InjectionConstructor / InjectionProperty / InjectionMethod según su Arquitectura de inyección dentro del ResolvedParameter <T> ("nombre") para obtener una instancia de un Objeto registrado previamente en el contenedor.
En su caso, este Objeto debe estar registrado con un Nombre, y para el mismo ingreso necesita ContainerControlledLifeTimeManager () que LifeTimeManager.
fuente
Resolve
toma una colección deResolverOverride
yInjectionConstructor
no es unResolverOverride
.La respuesta muy corta es: no. Actualmente, Unity no tiene forma de pasar parámetros al constructor que no sean constantes o inyectados, que he podido encontrar. En mi humilde opinión, eso es lo más importante que le falta, pero creo que es por diseño y no por omisión.
Como señala Jeff Fritz, en teoría podría crear un administrador de por vida personalizado que sepa qué instancia de contexto inyectar en varios tipos, pero ese es un nivel de codificación que parece obviar el propósito de usar Unity o DI en primer lugar.
Podría dar un pequeño paso atrás de la DI completa y hacer que las implementaciones de su repositorio sean responsables de establecer sus propios contextos de datos. La instancia de contexto aún se puede resolver desde el contenedor, pero la lógica para decidir cuál usar tendría que ir a la implementación del repositorio. No es tan puro, ciertamente, pero eliminaría el problema.
fuente
Otra alternativa que podría utilizar (realmente no sé si es una buena práctica o no) es crear dos contenedores y registrar una instancia para cada uno:
espero que esto también ayude
fuente
NotDan, creo que puede haber respondido a su propia pregunta en los comentarios a lassevk.
Primero, usaría LifetimeManager para administrar el ciclo de vida y la cantidad de instancias de IDataContext que crea Unity.
http://msdn.microsoft.com/en-us/library/cc440953.aspx
Parece que el
ContainerControlledLifetimeManager
objeto le brindará la administración de instancias que necesita. Con ese LifetimeManager en su lugar, Unity debería agregar la misma instancia de IDataContext a todos los objetos que requieren una dependencia de IDataContext.fuente