unity type transientlifetimemanager register lifetimemanager ioc injection dependency container c# .net unity-container ioc-container

c# - type - Especificar el constructor para el contenedor Unity IoC para usar



unity container register type (4)

Por defecto, Unity elige un constructor con un número máximo de argumentos. Para anular esto, decore el constructor requerido con InjectionConstructorAttribute .

Estoy usando el contenedor Unity IoC para resolver mis objetos. Sin embargo, me encontré con un problema. Cuando tengo más de un constructor, ¿cómo sabe Unity cuál usar? Parece usar el que tiene parámetros cuando tengo uno con y sin él. ¿Puedo decir explícitamente qué constructor usar?

Específicamente, tuve un caso similar a la siguiente clase Person con dos constructores. En este caso, quiero que el contenedor IoC use el constructor predeterminado, sin parámetros, pero elige el que tiene los parámetros.

public class SomeValueObject { public SomeValueObject(string name) { Name = name; } public string Name { get; set; } } public class Person { private string _name; public Person() { _name = string.Empty; } public Person(SomeValueObject obj) { _name = obj.Name; } }

Obviamente, esto falla, ya que no puede crear el SomeValueObject, sin saber qué inyectar a su parámetro de cadena. El error que da es:

La resolución de la dependencia falló, type = "MyApp.Person", name = "". El mensaje de excepción es: La operación de compilación actual (clave de compilación Build Key [MyApp.Person, null]) falló: El parámetro obj no se pudo resolver al intentar llamar al constructor MyApp.Person (MyApp.SomeValueObject obj). (Tipo de estrategia BuildPlanStrategy, índice 3)

El registro del contenedor:

Container.RegisterType<Person, Person>(new Microsoft.Practices.Unity.ContainerControlledLifetimeManager());

Y la resolución:

var person = Container.Resolve<Person>();


Realmente tengo que señalar que la forma en que está usando la inyección de dependencia en esta instancia es simplemente incorrecta. El contenedor debería poder inyectar SomeValueObject en la construcción.

Lo que probablemente debería hacer es registrar un objeto predeterminado de SomeValueObject que la propiedad string.Empty devuelve string.Empty en string.Empty lugar.


Regístrelo así en su lugar:

container.RegisterType<Person>(new InjectionConstructor());

También puede agregar LifetimeManager utilizando una sobrecarga del método RegisterType.

Dicho esto, al modelar para DI, tu vida será mucho más fácil si tienes contructors inequívocos (es decir, no hay constructores sobrecargados).


Inyección de múltiples constructores utilizando un atributo

Cuando una clase objetivo contiene más de un constructor con el mismo número de parámetros, debe aplicar el atributo InjectionConstructor al constructor que el contenedor de Unity usará para indicar qué constructor usará el contenedor. Al igual que con la inyección automática del constructor, puede especificar los parámetros del constructor como un tipo concreto, o puede especificar una interfaz o clase base para la cual el contenedor de Unity contiene una asignación registrada.