IoC en el "mundo real": ¿cómo manejar muchas clases? [cerrado]

Ahora tengo una buena comprensión de los contenedores DI e IoC, pero no estoy seguro de cómo manejar los aspectos del mundo real de tener docenas de clases en múltiples "módulos" (DLL, lo que sea). Casi todos los ejemplos que he visto de IoC hacen uso de tal vez un puñado de clases y configuran manualmente el contenedor en el método Main (o Global.asax si es una aplicación web) que es una locura para las aplicaciones a gran escala como lo haría tener cientos de líneas simplemente usando el For<I>().Use<T>() sintaxis para configurar todo.

He investigado un poco y este parece ser el propósito de las clases Registry (StructureMap) y Kernel (Ninject) (esos son los dos contenedores de IoC con los que estoy familiarizado, por lo que se mencionan aquí, estoy seguro otros contenedores de IoC tienen cosas similares).

Ahora, mi pregunta es si tiene la intención de crear un Registro diferente (he estado jugando con StructureMap, así que me quedaré con esa nomenclatura) que corresponda a cada agrupación en su aplicación (por ejemplo, Repositorios, Entidades, Servicios) en digamos un Biblioteca de clases de "Infraestructura" y luego conectar esas clases en el punto de entrada de la aplicación principal. Supongo que podría ir más allá y tener un registro para cada agregado (para usar el término DDD) y luego conectar todos ellos en clases de registro aún más amplias que abarquen una sección completa de una aplicación (por ejemplo, la parte CRM de una aplicación LOB más grande podría tener varios agregados por sí solo, por lo que tendría un registro que conecta cada agregado, y luego un registro más grande que combina todos los registros agregados ... ¡Espero que tenga sentido!)

Para un ejemplo básico:

// MyApp.Infrastructure
class ServiceRegistry : Registry 
{
    public ServiceRegistry()
    {
        For<IOrderService>().Use<OrderService>();
        // other services...
    }
}

class RepositoryRegistry: Registry
{
    public RepositoryRegistry()
    {
        For<IOrderRepository>().Use<OrderRepository>();
        // other repositories...
    }
}

// other registry files e.g. for Entities

// Global.asax or Program.cs or whatever entry point
ObjectFactory.Initialize(x => {
    x.AddRegistry<ServiceRegistry>();
    x.AddRegistry<RepositoryRegistry>();
    // other registries
});

¿Es esta la forma preferida de manejar aplicaciones del mundo real que pueden tener docenas, si no cientos, de clases organizadas lógicamente?

preguntado el 08 de enero de 11 a las 15:01

5 Respuestas

En StructureMap, ya se proporciona un agregador de registros. Eche un vistazo a la documentación de StructureMap en escaneo de ensamblajes. Debe crear un registro para cada ensamblado (puede hacer varios en un solo ensamblado, pero no hay ningún beneficio obvio).

A continuación, puede utilizar la función de escaneo para encontrar todos los registros. También querrá hacer uso de las convenciones de registro (en el Scan() cláusula) para que no tenga que registrar explícitamente cada implementación.

ObjectFactory.Initialize(x => {
  x.Scan(s => {
    // Add the current assembly
    s.TheCallingAssembly();

    // Add all assembly from a specified path
    s.AssembliesFromPath("Extensions");

    // Automatically look and execute registries
    s.LookForRegistries();

    // specify some conventions
    s.WithDefaultConventions();
  });
});

Respondido el 08 de enero de 11 a las 22:01

Para proyectos más grandes como este, probablemente querrá favorecer la convención sobre la configuración. StructureMap, por ejemplo, tiene un escáner de convenciones predeterminado o puede escribir un escáner personalizado. Eche un vistazo aquí: http://codebetter.com/jeremymiller/2009/01/20/create-your-own-auto-registration-convention-with-structuremap/

Entonces, digamos que generalmente usa inyección de constructor y su programa de arranque de IoC puede ver exactamente una implementación para interfaces en un ensamblado dado, simplemente lo configuraría para escanear ese ensamblaje y conectará las dependencias del constructor automáticamente.

Respondido el 08 de enero de 11 a las 19:01

Cuando uso Spring, tengo archivos de configuración separados por capa (web, servicio, persistencia, etc.). Como todas las técnicas de estratificación, estas mantienen configuraciones que lógicamente deberían agruparse en un lugar que deja clara la relación.

Toda la informática tiene esto en común: lidiar con la complejidad descomponiéndola en trozos más pequeños y manejables.

Respondido el 08 de enero de 11 a las 19:01

Incluso el nombre Registry puede resultar confuso, aunque proviene del libro de Fowler de patrones de diseño de aplicaciones empresariales. Podría considerar llamar al punto de entrada la raíz de composición de su aplicación (consulte Inyección de dependencia de .NET de Marc Seemans, libro de manning). De todos modos, debe tener una raíz de composición para todas y cada una de las aplicaciones, no compartir las raíces de composición entre aplicaciones, ya que vinculan interfaces con ellas, mientras que algunas aplicaciones pueden no necesitar todas sus interfaces.

Espero que tenga algún sentido :)

Respondido el 08 de enero de 11 a las 19:01

Es posible que desee utilizar la función de "cableado automático" de IoC. Por ejemplo, si ha separado implementaciones para sus interfaces en diferentes ensamblajes y solo está distribuyendo una versión, IoC-Container podrá encontrar una implementación adecuada automáticamente y no tendrá que decirle manualmente al contenedor qué implementación debe usar al resolver la dependencia.

Se llama "Autowiring" (byType, byName, ...) en Spring.Net y StructureMaps.

Respondido el 08 de enero de 11 a las 19:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.