2012-01-23 27 views
6

Estoy buscando un IoC Container realmente simple y liviano, cuya fuente C# se puede incluir en mi propio proyecto (por lo tanto, no hacer una referencia externa).Contenedor IoC Project-Embedded

La razón de esto es que estoy escribiendo una infraestructura y me gustaría proporcionar un solo archivo .dll, sin dependencias adicionales.

Asimismo, no quiero ILMerge mi montaje con la Asamblea de la COI ..

pensé en MEF, algunas otras sugerencias?

+0

Es posible que desee etiquetar este .net para obtener más sugerencias. –

+1

mire esta pregunta: http://stackoverflow.com/questions/2515124/whats-the-simplest-ioc-container-for-c hay un ejemplo en línea –

+6

Si está escribiendo una biblioteca, no debería tener que use un Contenedor DI en absoluto: http://stackoverflow.com/questions/2045904/dependency-inject-di-friendly-library/2047657#2047657 –

Respuesta

3

Si usa .NET 4.0, tiene MEF incluido.

Para .NET 2 Una vez escribí algo similar usando interfaces y Reflection. Hay muchos tutoriales que describen ese proceso. Incluso si puedes usar MEF, vale la pena intentar algunos tutoriales de reflexión, ya que así funciona MEF.

También echa un vistazo a this pregunta que tiene algunas buenas respuestas. TinyIoC parece que es solo un único archivo fuente.

+0

Gracias por TinyIoC. Parece exactamente lo que estaba buscando. – dux2

0

me gusta mucho Castle.Windsor que es de código abierto, por lo que habría que agregar los archivos de código correspondientes a su proyecto

+2

Windsor no es mi definición de contenedor liviano. Incluye alrededor de 4 ensamblajes y una gran cantidad de archivos/clases fuente. – dux2

0

En realidad no es tan difícil de rodar su propio contenedor, dependiendo del tipo de características que necesita. Sin embargo, es muy fácil crear pérdidas al hacerlo, así que supongo que probablemente desee utilizar una solución probada y probada.

MEF es usado por algunos como un contenedor pero (notable) otros dicen que MEF is not an IOC container, en esencia MEF fue diseñado para ser una arquitectura de complemento no un contenedor de inyección de dependencia.

Teniendo en cuenta todo esto, le recomiendo que inserte el código fuente completo para el contenedor de su elección en su aplicación o utilice una herramienta para fusionar su ensamblaje con el suyo. ILMerge es una herramienta que podría hacer eso, la mayoría de los ofuscadores comerciales pueden ayudarte a hacer esto también. Si está construyendo una biblioteca o aplicación comercial, definitivamente recomendaría utilizar un ofuscador apropiado de todos modos.

+0

Como dije en mi pregunta, estoy dispuesto a insertar el código fuente del contenedor en mi propio proyecto, pero estoy buscando un contenedor probado con un número mínimo de archivos y clases. No ILMerge por favor. – dux2

+0

¿Cuáles son los requisitos para el contenedor? ¿Qué tipo de soporte de ciclo de vida necesitas? ¿Desea una configuración XML, una API de configuración fluida o está contento con la configuración explícita de cada tipo? –

+0

Me gustaría configurar el contenedor por código. Me gustaría soporte para singleton y ciclos de vida transitorios. – dux2

3

Si no es necesario ningún procedimiento especial, un contenedor DI puede ser muy corta:

public class Container 
{ 
    private readonly Dictionary<Type,Func<Container,object>> factories; 
    private readonly Dictionary<Type,object> cache; 

    public Container() 
    { 
     this.factories = new Dictionary<Type,Func<Container,object>>(); 
     this.cache = new Dictionary<Type,object>(); 
    } 

    public void Register<TContract>(Func<Container,TContract> factory) 
    { 
     // wrap in lambda which returns object instead of TContract 
     factories[typeof(TContract)] = c => factory(c); 
    } 

    public TContract Get<TContract>() 
    { 
     var contract = typeof(TContract); 
     if (!cache.ContainsKey(contract)) 
     { 
      this.cache[contract] = this.factories[contract](this); 
     } 
     return (TContract)this.cache[contract]; 
    } 
} 

cual se utilizaría la siguiente manera:

var container = new Container(); 
container.Register<ICar>(c => new Car(
    c.Get<IEngine>(), c.Get<IWheel>())); 
container.Register<IWheel>(c => new Wheel()); 
container.Register<IEngine>(c => new Engine()); 

var car = container.Get<ICar>(); 

Aún más minimalista habría que hacer la dependencia inyección sin un contenedor:

IWheel wheel = new Wheel(); 
IEngine engine = new Engine(); 
ICar car = new Car(engine, wheel); 

sin embargo, para los gráficos de objetos complejos se pueden obtener rápidamente compli para mantener el orden de construcción correcto durante las refactorizaciones. El contenedor no tiene este problema.

Cuestiones relacionadas