2012-01-24 10 views
12

Autofac tiene módulos, Windsor tiene Instaladores y Registros StructureMap ... con Simple Injector ¿cómo puedo empaquetar la lógica de configuración en clases reutilizables?¿Cómo puedo emular Módulos/Instaladores/Registros con Simple Injector

que he intentado:

public interface IModule { } 

public class FooModule : IModule 
{ 
    public FooModule(SimpleInjector.Container container) 
    { 
     container.RegisterSingleton<IBar, Bar>(); 
     container.RegisterSingleton<IFoo, Foo>(); 
    } 
} 

y lo uso en la raíz Composición:

public static void Main(string[] args) 
{ 
    var container = new SimpleInjector.Container(); 
    container.RegisterCollection<IModule>(new FooModule(container)); 
    ... 
} 

Sin embargo, FooModule depende de envase y tal vez en no es una buena práctica ... ver http://code.google.com/p/autofac/wiki/BestPractices :

Si los componentes tienen una dependencia en el contenedor, Mire cómo están utilizando el contenedor para recuperar servicios y agregue esos servicios a los argumentos del constructor del componente (dependencia inyectado) en su lugar.

+0

Tenga en cuenta que, incluso con Autofac, su 'FooModule' dependerá del contenedor (o con Autofac,' ContainerBuilder, ya que Autofac divide el contenedor en dos tipos). Eche un vistazo a [esta documentación de Autofac] (http://code.google.com/p/autofac/wiki/StructuringWithModules) y verá claramente que los módulos toman esta dependencia. Para un módulo, simplemente necesita el contenedor, pero eso no importa ya que un módulo será parte de su raíz de composición. – Steven

Respuesta

14

Una función de 'módulo' se deja deliberadamente fuera de la biblioteca del núcleo del Inyector simple, pero hay un SimpleInjector.Packaging NuGet package que le permite hacer esto. 'Paquete' es el término que usa Simple Injector. Sin embargo, esta biblioteca no es más que una interfaz IPackage y dos métodos de extensión. Se puede lograr el mismo escribiendo código como este:

Un paquete:

public static class BootstrapperPackage 
{ 
    public static void RegisterServices(Container container) 
    { 
     container.Register<IBar, Bar>(Lifestyle.Scoped); 
     container.Register<IFoo, Foo>(Lifestyle.Singleton);    
    } 
} 

En la raíz de su composición:

public static void Main(string[] args) 
{ 
    var container = new SimpleInjector.Container(); 

    BootstrapperPackage.RegisterServices(container); 

    ... 
} 

La diferencia con el SimpleInjector.Packaging NuGet package es que este paquete define una interfaz para usted, y le permite cargar dinámicamente múltiples paquetes en una sola línea:

public class BusinessLayerPackage : IPackage 
{ 
    public void RegisterServices(Container container) 
    { 
     container.Register<IBar, Bar>(Lifestyle.Scoped); 
     container.Register<IFoo, Foo>(Lifestyle.Singleton);    
    } 
} 

public static void Main(string[] args) 
{ 
    var container = new SimpleInjector.Container(); 

    container.RegisterPackages(AppDomain.CurrentDomain.GetAssemblies()); 
} 

Sin embargo, si usted realmente no necesita carga dinámica, utilizando métodos estáticos (como se muestra arriba) se prefiere, porque tiene las siguientes ventajas:

  • Hace que la carga de módulos muy explícita y visible.
  • Hace que sea fácil seleccionar qué módulos cargar y cuáles no.
  • Facilita la transferencia de valores adicionales a los métodos RegisterServices, como los valores de configuración que requiere dicho módulo. Esto evita que el módulo tome una dependencia dura del sistema de configuración.

Para obtener más información, lea this.

+0

Gracias Steven, ... pero ¿es correcto pasar el contenedor a otras clases? – o3o

+0

No, no lo es, pero un módulo no es parte del código de la aplicación, sino parte de [raíz de la composición] (http://blog.ploeh.dk/2011/07/28/CompositionRoot.aspx), que lo convierte en un componente de infraestructura. Está bien usar el contenedor dentro de los componentes de su infraestructura. Mark Seemann describe esto claramente [aquí] (http://blog.ploeh.dk/2011/08/25/ServiceLocatorRolesVsMechanics.aspx). – Steven

+1

¿Por qué esta función quedó fuera de la biblioteca central? – Sam

Cuestiones relacionadas