Pregunta

Estoy utilizando la Unidad 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 parámetro IDataContext, y quiero Unidad para inicializar el repositorio con el contexto que lo paso. También tenga en cuenta que IDataContext no se ha registrado en la Unidad (no quiero 3 casos de IDataContext).

¿Fue útil?

Solución

A partir de hoy se han añadido esta funcionalidad:

Está en la última gota aquí:

http://unity.codeplex.com/SourceControl/changeset/view/33899

discusión sobre ella aquí:

http://unity.codeplex.com/Thread/View.aspx? ThreadId = 66434

Ejemplo:

container.Resolve<IFoo>(new ParameterOverrides<Foo> { { "name", "bar" }, { "address", 42 } });"

Otros consejos

<2 centavos>

¿Qué pasaría si más adelante decide utilizar un servicio diferente que requiere más o menos que sólo el contexto?

El problema con parámetros de constructor y la COI es que los parámetros son en última instancia atados con el tipo de hormigón que se utiliza, en lugar de ser parte del contrato que la interfaz de servicio define.

Mi sugerencia sería que o bien resolver el contexto así, y creo que la Unidad debe tener una forma para que usted pueda evitar la construcción de 3 instancias de ella, o se debe considerar un servicio de fábrica que tiene una manera para que usted pueda construir el objeto.

Por ejemplo, ¿qué ocurre si más adelante decide construir un repositorio que no se basa en una base de datos tradicional en absoluto, pero en lugar de utilizar un archivo XML para producir maniquí-datos para la prueba? ¿Cómo haría usted para alimentar el contenido XML a ese constructor?

COI se basa en la disociación de código, mediante la vinculación en el tipo y la semántica de los argumentos de los tipos de hormigón, que realmente no lo ha hecho el desacoplamiento correctamente, todavía hay una dependencia.

"Este código puede hablar con cualquier tipo de depósito, posiblemente, siempre y cuando se implementa esta interfaz .... Ah, y utiliza un contexto de datos".

Ahora, sé que otros contenedores IoC tienen soporte para esto, y lo tenía en mi primera versión de mi propia así, pero en mi opinión, que no pertenece a la etapa de resolución.

Gracias chicos ... el mío es similar al mensaje por "existir". Vea a continuación:

        IUnityContainer container = new UnityContainer();
        container.LoadConfiguration();

        _activeDirectoryService = container.Resolve<IActiveDirectoryService>(new ResolverOverride[]
        {
            new ParameterOverride("activeDirectoryServer", "xyz.adserver.com")
        });

Puede utilizar InjectionConstructor / InjectionProperty / InjectionMethod dependiendo de su Arquitectura de inyección dentro del ResolvedParameter ( "nombre") para obtener una instancia de un objeto registrado previamente en el contenedor.

En el caso de que este objeto debe ser registrado con un nombre, y por la misma insance necesita ContainerControlledLifeTimeManager () como el LifeTimeManager.

_unityContainer.RegisterType<IDataContext,DataContextA>("DataContextA", new ContainerControlledLifeTimeManager());
_unityContainer.RegisterType<IDataContext,DataContextB>("DataContextB");

  var repositoryA = _unityContainer.Resolve<IRepositoryA>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextA")));

  var repositoryB = _unityContainer.Resolve<IRepositoryB>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextA")));

  var repositoryA2 = _unityContainer.Resolve<IRepositoryA>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextB")));

La respuesta corta es: no. La unidad no tiene manera de pasar parámetros en el constructor que no son constantes o inyectado, que he podido encontrar. En mi humilde opinión esa es la única cosa más grande que le falta, pero creo que es por diseño y no por omisión.

Como Jeff Fritz señala, podría, en teoría, crear un gestor de toda la vida a medida que sabe qué instancia de contexto para inyectar en varios tipos, pero eso es un nivel de codificación dura de lo que parece obviar el propósito de utilizar la unidad o DI en el primer sitio.

Usted podría tomar un pequeño paso atrás de la plena DI y hacer sus implementaciones del repositorio responsable de establecer sus propios contextos de datos. El contexto ejemplo puede todavía ser resuelto desde el contenedor, pero la lógica para decidir cuál usar tendrían que entrar en la implementación del repositorio. No es tan pura, sin duda, pero sería deshacerse del problema.

Otra alternativa podría utilizar (no se sabe muy bien si es una buena práctica o no) es la creación de dos contenedores y el registro de una instancia para cada uno:

IDataContext context = _unityContainer.Resolve<IDataContext>();
_unityContainer.RegisterInstance(context);
var repositoryA = _unityContainer.Resolve<IRepositoryA>(); //Same instance of context
var repositoryB = _unityContainer.Resolve<IRepositoryB>(); //Same instance of context


//declare _unityContainer2
IDataContext context2 = _unityContainer2.Resolve<IDataContext>(); //New instance
_unityContainer2.RegisterInstance(context2);
var repositoryA2 = _unityContainer2.Resolve<IRepositoryA>(context2); //will retrieve the other instance

esperanza esto ayuda también

NotDan, creo que es posible que haya respondido a su propia pregunta en los comentarios a lassevk.

En primer lugar, me gustaría utilizar un LifetimeManager para gestionar el ciclo de vida y el número de casos de IDataContext que crea la Unidad.
http://msdn.microsoft.com/en-us/library/cc440953. aspx

Parece que el objeto ContainerControlledLifetimeManager le dará la gestión de instancias que necesita. Con eso LifetimeManager en su lugar, la unidad debe añadir la misma instancia de la IDataContext a todos los objetos que requieren una dependencia IDataContext.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top