12

Podría parecer una pregunta estúpida, porque en mi código que todo funciona, pero he registrado un producto único de esta manera con mi contenedor Unidad _ambientContainer:UnityContainer.Resolve o ServiceLocator.GetInstance?

_ambientContainer.RegisterType<Application.StateContext>(new ContainerControlledLifetimeManager()); 

Con el fin de evitar que usar mi local de campo, uso :

get { 
    return ServiceLocator.Current.GetInstance<Application.StateContext>(); 
} 

dentro de mi propiedad para obtener una instancia de mi objeto. De esta forma siempre obtengo la misma instancia (Application.StateContext sigue siendo un singleton) o ¿crea GetInstance una nueva?

¿Es mejor utilizar el campo local _ambientContainer en su lugar?

get { 
    return _ambientContainer.Resolve<Application.StateContext>(); 
} 

Gracias.

Respuesta

7

Preferiblemente se deben evitar en ambos sentidos de (ab) utilizando su contenedor.

El ServiceLocator is considered an anti-pattern en la arquitectura de aplicaciones modernas.

+1

¿Tiene alguna sugerencia de una alternativa? (específico para el código de ejemplo en la pregunta?) – Adam

+0

@Adam ¿Una alternativa a qué código? ¿El getter? O el registro de 'Application.StateContext'? El autor no dijo qué tipo de aplicación usa (asp.net/mcv, winforms, wpf, console, wcf ...) por lo que no puedo decir que pusiera el código de registro. Cada tipo de aplicación tiene una [raíz de composición] diferente (http://blog.ploeh.dk/2011/07/28/CompositionRoot.aspx). En cuanto a la llamada al localizador de servicios: haga que 'StateContext' sea un parámetro de ctor de aquellas clases que lo necesiten. Eso hace que la dependencia sea explícita e intercambiable (por ejemplo, para las pruebas). –

+1

Cualquier patrón es un patrón anti si lo usa de forma incorrecta. TODAS las bibliotecas DI usan la ubicación del servicio debajo de las cubiertas, de lo contrario no funcionan. ¡No creas todo lo que lees en internet! – JBeckton

15

que pasa alrededor de las instancias del contenedor a clases de consumo no es generalmente una buena idea, ya que ya no están garantizados para tener un solo lugar en su aplicación en la que se registran los componentes y servicios (conocido como el Composition Root) .

Las clases deben declarar sus dependencias en su API pública, a ser posible por specifying them as constructor arguments, que el envase proporcionará automáticamente una instancia para cada vez que se ha pedido para resolver un tipo específico (un proceso conocido como Autowiring).

Dependency Injection es generalmente the preferred choice pero no siempre es aplicable. En los casos que usan un Service Locator, como lo está haciendo en su ejemplo, es el la siguiente mejor solución al decouple a class from its dependencies.

En conclusión, si la Inyección de Dependencias no es una opción, evitaría que mis clases hagan referencia directamente al contenedor y, en su lugar, que accedan a él a través de un Localizador de Servicios.