2008-11-11 17 views
9

? Estoy empezando con los contenedores de IoC, así que le pido disculpas si esta es una pregunta estúpida.¿Un contenedor de IoC reemplaza el uso de las fábricas

que tienen un código como el siguiente en una aplicación

internal static class StaticDataHandlerFactory 
    { 
     public static IStaticDataHandler CreateHandler(StaticDataUpdate staticDataUpdate) 
     { 
      if (staticDataUpdate.Item is StaticDataUpdateOffice) 
      { 
       return new OfficeUpdateHandler(); 
      } 

      if (staticDataUpdate.Item is StaticDataUpdateEmployee) 
      { 
       return new EmployeeUpdateHandler(); 
      } 

      if (staticDataUpdate.Item == null) 
      { 
       throw new NotImplementedException(
        string.Format("No static data provided")); 
      } 
      else 
      { 
       throw new NotImplementedException(
        string.Format("Unimplemented static data type of {0}", staticDataUpdate.Item.GetType().FullName)); 
      } 
     } 
    } 

Se trata básicamente de una fábrica simple que devuelve la estrategia correcta para el manejo de los datos de entrada.

¿Un contenedor IoC me permite eliminar código como este? Es decir: ¿me permitiría elegir dinámicamente una implementación concreta para cargar en función del tipo de parámetro de entrada?

¿O estoy fuera de curso aquí?

Respuesta

7

En realidad, aunque es posible reemplazar parte del código con un sistema de inversión de control, no es obvio para mí es una buena idea. La inyección de dependencia tiende a ser lo mejor para la configuración de sistemas, no la creación dinámica de objetos. Para decirlo de otra manera, el contenedor en sí es una gran variable global y, como tal, debería aparecer en gran parte de tu código.

Como un lado, el código parece estar violando el Law of Demeter. Parece que el parámetro debe ser del tipo "StaticDataUpdateItem" en lugar de "StaticDataUpdate". Con eso observado, hay un argumento bastante fuerte para reescribir este código como una llamada a método en StaticDataUpdateItem.

que utilizan COI bastante fuerte, pero la creación dinámica de objetos es aún mejor tratadas con el uso de una Abstract Factory. En resumen, si no le gusta la idea de agregar un método al elemento en sí para generar el identificador, es probable que el código se haya dejado tal como está.

0

La respuesta corta es sí, lo permite. Este blog post muestra una manera elegante de elegir la implementación en tiempo de ejecución usando Windsor. El autor, Ayende, elabora here y here.

No he intentado esto todavía, pero espero hacerlo pronto.

2

No está muy lejos del rumbo; De la manera en que lo entiendo, eres muy cercano.

La forma más común en que estructuraría este tipo de cosas es convertir su clase Factory en su contenedor IoC, simplemente permitiendo que UpdateHandlers que se devuelven se especifiquen mediante Dependency Injection. Entonces, en lugar de tener la lógica en su código que especifica que StaticDataUpdateOffice significa devolver OfficeUpdateHandler, puede convertir su código simplemente diciendo que StaticDataUpdateOffice devuelve lo que contenga una variable (recientemente especificada) m_officeUpdateHandler; siempre que su Framework se asegure de establecer el valor de m_officeUpdateHandler antes de invocar su fábrica, ya está listo. Y puede cambiar el valor de m_officeUpdateHandler a cualquier cosa que desee en tiempo de ejecución a medida que cambien sus necesidades.

Esta Inyección de Dependencia le permite tener control sobre el proceso de Inversión de Control; puede tener una fábrica simple que devuelva sus manejadores, y puede abstraer la lógica que controla qué manejador se devuelve a una ubicación diferente, según corresponda.

Nota: mi experiencia con este tipo de cosas está muy determinada por mi experiencia (muy positiva) con Spring, por lo que puede cambiar mi interpretación de su pregunta (y la respuesta).

0

Estoy de acuerdo con las otras respuestas aquí, eso sí, puedes hacerlo de esa manera. Pero, ¿por qué no usas un genérico?

public static IStaticDataHandler CreateHandler<T>(params object[] args) 
{... 

donde args se pueden pasar como argumentos del ctor (a, por ejemplo, Activador).

+1

Debido a que los genéricos se resuelven en tiempo de compilación - que ha de tomar su decisión sobre la base de qué tipo de artículo se transporten mercancías, una decisión en tiempo de ejecución. – Bevan

+1

No tiene que resolver genéricos en tiempo de compilación. Mira Type.MakeGenericType() si no me crees. – dviljoen

-2

todavía tengo que leer cualquier palabra aquí que tiene mucho sentido.

IoC es más para config?

creación del objeto dinámico es mejor qué? Genéricos? Esto está fuera del tema.

1) COI no es más que un buen ahorro de tiempo en comparación con la aplicación de la 'composición sobre la especialización/herencia' Evangelio.

lo que la regla # 1 para el uso de un COI que debe ser muy cansado de tener que lidiar con los constructores largas que siguen el 'se unen para contratar no aplicación'.

Dicho de otra manera, este es el patrón estratégico como la alternativa sobre el patrón de la plantilla por las mismas razones (encapsular ...) ... PERO es más trabajo crear todos los tipos adicionales de interfaz/resumen y es más trabajo para hacerlo cada vez con toda la IServiceProvicerThis y IResolverThat ... Si no está cansado de tener que cumplir con los contratos de código tediosamente como:

IInterestingService interesante = ... se obtiene una instancia sin embargo ..

agregar aproximadamente tres líneas más como esta ..

luego

servicio IAmazementService = new AmazementService (interesante, thesecondstrategy, thethird, etc ...)

Eso pasa de moda. Entonces IoC nunca es una pregunta porque cualquiera que sea lo suficientemente inteligente como para codificar usando un diseño sólido lo sabría mejor. Aquellos que preguntan tienen todas las respuestas incorrectas.

Así que si es que cumplen con lo anterior, entonces absolutamente. Los contenedores de IoC están en el gancho para hacer todo el trabajo 'creacional' que pueda beneficiarse de dejar que se ocupen de ellos. Y la abstracción creacional más común sobre nueva explícita es Mr. Factory.

Damon

Cuestiones relacionadas