Pregunta

Recién estoy comenzando con los contenedores de IoC, así que disculpen si esta es una pregunta estúpida.

Tengo 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));
            }
        }
    }

Es básicamente una fábrica simple que devuelve la estrategia correcta para manejar los datos de entrada.

¿Un contenedor IoC me permitiría eliminar un 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í?

¿Fue útil?

Solución

En realidad, aunque es posible reemplazar parte del código con una inversión del sistema de control, no es obvio para mí que sea una buena idea. La inyección de dependencia tiende a ser la mejor para la configuración de sistemas, no para 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 su código.

Como un aparte, el código parece estar violando el Ley de 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 al método en el StaticDataUpdateItem.

Utilicé bastante IoC, pero la creación dinámica de objetos todavía se maneja mejor usando un patrón abstracto de fábrica. 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 quede como está.

Otros consejos

No estás lejos del rumbo; según tengo entendido, estás bastante cerca.

La forma más común de estructurar este tipo de cosas es convertir su clase Factory en su contenedor de IoC, simplemente permitiendo que los UpdateHandlers que se devuelven se especifiquen mediante Inyección de dependencias. Entonces, en lugar de tener la lógica en su código que especifica que StaticDataUpdateOffice significa devolver OfficeUpdateHandler, puede convertir su código en simplemente decir que StaticDataUpdateOffice devuelve lo que sea que contenga una variable m_officeUpdateHandler (recién especificada); siempre que su Framework se asegure de establecer el valor de m_officeUpdateHandler antes de invocar su fábrica, está listo para comenzar. Y puede cambiar el valor de m_officeUpdateHandler a lo 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 controladores, y puede abstraer la lógica que controla qué controlador se devuelve a una ubicación diferente, según corresponda.

Nota: mi experiencia con este tipo de cosas está fuertemente impulsada por mi (muy positiva) experiencia con Spring, y eso puede influir en mi interpretación de su pregunta (y la respuesta).

La respuesta corta es sí, lo permite. Esta publicación de blog muestra Una forma ingeniosa de elegir la implementación en tiempo de ejecución con Windsor. El autor, Ayende, elabora aquí y aquí .

Todavía no lo he intentado, pero espero hacerlo pronto.

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

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

donde los argumentos pueden pasarse como argumentos de ctor (a, por ejemplo, Activador).

Todavía no he leído ninguna palabra aquí que tenga mucho sentido.

¿IoC es más para config?

La creación dinámica de objetos es mejor, ¿qué? Genéricos? Todo esto está fuera de tema.

1) IoC no es más que un buen ahorro de tiempo en comparación con la implementación del evangelio 'composición sobre especialización / herencia'.

Entonces, la regla # 1 para usar un IoC es que deberías estar realmente cansado de tener que lidiar con constructores largos que siguen el 'enlace al contrato, no la implementación'.

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

IInterestingService interesting = ... sin embargo, obtienes una instancia ...

agregue unas tres líneas más como esta ...

luego

Servicio IAmazementService = nuevo AmazementService (interesante, esta estrategia, tercera, etc.)

Eso envejece. Por lo tanto, IoC nunca es una pregunta porque cualquier persona lo suficientemente inteligente como para codificar utilizando un diseño sólido lo sabría mejor. Los que preguntan tienen todas las respuestas incorrectas.

Entonces, si efectivamente cumple con lo anterior, absolutamente. Los contenedores de IoC están enganchados para hacer todo el trabajo 'creativo' que pueda beneficiarse al permitirles lidiar. Y la abstracción creacional más común sobre las novedades explícitas es Mr. Factory.

Damon

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top