2009-11-06 12 views
9

Esto es lo que quiero de contenedor DI:qué contenedor DI va a satisfacer esta

public class Class 
{ 
    public Class(IDependency dependency, string data) { } 
} 

var obj = di.Resolve<Class>(() => new Class(null, "test")); 

Puntos de interés:

  1. puede resolver tanto la dependencia y los datos en el constructor.
  2. Puede usar la sintaxis de tipo seguro para pasar los parámetros del constructor (la sintaxis exacta puede variar). Sí, puedo hacerlo yo mismo obteniendo argumentos de constructor de (Expression.Body como NewExpression), pero necesitaré una forma de detectar qué argumentos están registrados en el contenedor.

Otro requisito importante es que me gustaría que mis componentes se recojan automáticamente, es decir, no deseo registrar Clase: quiero que IoC lo recoja porque sabe cómo resolver la dependencia de ID.

Además, la inyección de propiedades puede ser útil a veces, pero esto es opcional.

La cuestión es realmente acerca de la combinación de características - tener todas ellas - tipo seguro, parámetros, recogida automática ... Es fácil verificar una característica, pero una combinación de ellas no es fácil de verificar a menos que uno esté familiarizado con un contenedor particular y conozca sus características. Por lo tanto, la pregunta.

+0

No creo que haya ningún contenedor que admita ese tipo de sintaxis. Pero muchos (casi todos) contenedores admiten parámetros de contenedor explícitos, y probablemente con una sintaxis más limpia. –

+0

"Probablemente" no es la respuesta ... hasta donde sé puedo pasar la matriz de parámetros object [] pero obviamente no es seguro para tipos ... Puedo cambiar el orden de los parámetros y no sabré nada hasta el tiempo de ejecución . – queen3

+0

Por limpiador quise decir que no necesita usar explícitamente el código en su código, como lo hace arriba. En lugar de lo que escribió, ¿por qué no? 'Var obj = new Class (di.Resolve ()," test ");'? –

Respuesta

27

Creo que estarás mejor definiendo una fábrica abstracta que pueda crear tu clase.

public interface IFactory 
{ 
    MyClass Create(string data); 
} 

A continuación, puede crear una aplicación de IFactory así:

public class MyFactory : IFactory 
{ 
    private IDependency dependency; 

    public MyFactory(IDependency dependency) 
    { 
     if (dependency == null) 
     { 
      throw new ArgumentNullException("dependency"); 
     } 

     this.dependency = dependency; 
    } 

    #region IFactory Members 

    public MyClass Create(string data) 
    { 
     return new MyClass(this.dependency, data); 
    } 

    #endregion 
} 

En su contenedor, se registraría tanto MyFactory y la implementación de IDependency.

Ahora se puede utilizar el contenedor para resolver la fábrica, y la fábrica para obtener la clase:

var mc = container.Resolve<IFactory>().Create(data); 

Este enfoque es de tipo seguro completo y bien desacopla las dependencias de datos de la aplicación en tiempo de ejecución.

+0

¡Exactamente! ...................... –

+7

Puntos de bonificación por llamarlo por el nombre Abstract Factory, pero usando una interfaz.He visto mucha gente que cuando escuchan * Abstract * Factory va directo a la clase base abstracta. –

+2

Sí, lo sé, aunque en mi caso lo dudo porque para casos simples es excesivo duplicar constructor con interfaz, fábrica, constructor de fábrica, método Create, etc. Aunque es bueno para casos complejos, es demasiado "explosión DI" para cosas simples I pensar. Y la pregunta sigue siendo sobre el contenedor DI de registro automático. – queen3

Cuestiones relacionadas