what register objects locator injection fowler dependency control c# dependency-injection inversion-of-control service-locator common-service-locator

c# - register - inversion of control vs dependency injection



¿Cuándo usarías el Localizador de servicios comunes? (4)

He leído algo sobre el concepto de localizador de servicios últimamente. Es una forma de ayudar a reducir el acoplamiento, pero requiere el acoplamiento del código al localizador, no el contenedor que respalda el localizador, sino el localizador mismo. Es un intercambio, pero puede ser beneficioso en la situación correcta.

Una situación en la que puede ser útil es cuando tienes un código que no hace uso de DI, como el código heredado: ahora estoy en este barco. Incorporar los objetos requeridos a través de SL, en lugar de crearlos directamente, permite agregar algo de abstracción. Lo veo como un paso intermedio entre SL y DI / IoC.

He estado buscando en el Localizador de servicios comunes como una forma de abstraer mi contenedor de IoC, pero he notado que algunas personas están en contra de este tipo de cosas.

¿La gente recomienda nunca usarlo? Siempre usándolo? o a veces usándolo? Si a veces, ¿en qué situaciones lo usarías y en qué situaciones no lo usarías?


Imagine que está escribiendo código de biblioteca para ser utilizado por desarrolladores de terceros. Su código debe ser capaz de crear objetos de servicio que estos desarrolladores proporcionan. Sin embargo, no sabe qué contenedor de IoC usará cada uno de los llamantes.

Common Service Locator le permite hacer frente a lo anterior sin forzar un IoC determinado a sus usuarios.

Dentro de su propia biblioteca, es posible que desee registrar sus propias clases en la IoC, ahora es mucho más difícil ya que debe elegir una IoC para su propio uso que no se interponga en el camino de las personas que llaman.


Noté que uno de los argumentos en contra del uso de CSL es falso, porque los desarrolladores piensan que esta biblioteca solo es capaz de hacer el patrón de Localizador de servicios. Sin embargo, este no es el caso, porque también es fácil de usar con el patrón de Inyección de Dependencia.

Sin embargo, la biblioteca CSL fue especialmente diseñada para diseñadores de frameworks que necesitan permitir a los usuarios registrar dependencias. Debido a que la biblioteca llamará al CSL directamente, desde la perspectiva del marco estamos hablando del patrón SL, de ahí su nombre.

Sin embargo, como diseñador de marcos, tomar una dependencia del CSL no debería tomarse a la ligera. Para la usabilidad de su marco, normalmente es mucho mejor tener su propio mecanismo DI. Un mecanismo muy común es configurar dependencias en el archivo de configuración. Este patrón se usa en todo el framework .NET. Casi todas las dependencias pueden ser reemplazadas por otras. El patrón de proveedor de .NET se basa en esto.

Cuando usted, como diseñador de marcos, toma una dependencia del CSL, será más difícil para los usuarios usar su aplicación. Los usuarios deberán configurar un contenedor IoC y conectarlo al CSL. Sin embargo, no es posible que el marco valide la configuración como se puede hacer al usar el sistema de configuración .NET, que tiene todo tipo de soporte de validación.


Si tiene un código de biblioteca que necesita servicios y este código podría estar alojado en el contexto de un framework / tiempo de ejecución más grande, entonces el framework / runtime necesitaría proporcionar un mecanismo donde pueda ejecutar algún código personalizado al inicio, donde puede inicializar su contenedor y registrar dependencias. Un buen ejemplo de dónde CSL puede ser problemático es cuando se usa en el contexto de MSCRM. Puede ejecutar lógica de negocios personalizada registrando complementos que el marco MSCRM ejecuta en ciertos eventos. El problema con el que se encuentra es dónde ejecuta la lógica de registro ya que no hay ningún evento de "inicio" al que pueda suscribirse para configurar su contenedor DI. Incluso si pudiera configurar de algún modo su DI, tendría que colocar las bibliotecas CSL y DI en el GAC, ya que es la única forma de llamar a un código de terceros desde un complemento (un elemento más para agregar a su lista de comprobación de implementación). En escenarios como este, es mejor que tenga sus dependencias como parámetros de constructor que el código de llamada puede inicializar como lo considere apropiado (mediante la inyección del constructor o manualmente "actualizando" la implementación de la interfaz adecuada).