patterns - singleton service c#
Resumen del contenedor de IoC detrĂ¡s de un singleton: ¿Hacerlo mal? (4)
Solo una nota: Microsoft Patterns and Practices ha creado un localizador de servicio común ( http://www.codeplex.com/CommonServiceLocator ) que la mayoría de los principales contenedores de IoC implementarán en el futuro cercano. Puede comenzar a usarlo en lugar de su IDependencyResolver.
Por cierto: esta es la forma común de resolver su problema y funciona bastante bien.
En general, me gusta mantener una aplicación completamente ignorante del contenedor IoC. Sin embargo, me encontré con problemas donde necesitaba acceder. Para abstraer el dolor, uso un Singleton básico. Antes de correr hacia las colinas o sacar la escopeta, déjame revisar mi solución. Básicamente, el singleton de IoC no hace absolutamente nada, simplemente se delega en una interfaz interna que debe transferirse. He descubierto que esto hace que trabajar con Singleton sea menos doloroso.
A continuación está el contenedor IoC:
public static class IoC
{
private static IDependencyResolver inner;
public static void InitWith(IDependencyResolver container)
{
inner = container;
}
/// <exception cref="InvalidOperationException">Container has not been initialized. Please supply an instance if IWindsorContainer.</exception>
public static T Resolve<T>()
{
if ( inner == null)
throw new InvalidOperationException("Container has not been initialized. Please supply an instance if IWindsorContainer.");
return inner.Resolve<T>();
}
public static T[] ResolveAll<T>()
{
return inner.ResolveAll<T>();
}
}
IDependencyResolver:
public interface IDependencyResolver
{
T Resolve<T>();
T[] ResolveAll<T>();
}
Hasta ahora he tenido un gran éxito con las pocas veces que lo he usado (tal vez una vez cada pocos proyectos, realmente prefiero no tener que usar esto en absoluto) ya que puedo inyectar todo lo que quiero: Castle, un Stub, falsificaciones, etc.
¿Es este un camino resbaladizo? ¿Voy a encontrar problemas potenciales en el futuro?
He visto que incluso Ayende implementa este patrón en el código de Rhino Commons, pero desaconsejaría usarlo siempre que sea posible. Hay una razón por la cual Castle Windsor no tiene este código por defecto. StructureMap lo hace, pero Jeremy Miller se ha estado alejando de él. Idealmente, debe considerar el contenedor en sí con tanta sospecha como cualquier variable global.
Sin embargo, como alternativa, siempre puede configurar su contenedor para resolver IDependencyResolver como referencia a su contenedor. Esto puede sonar loco, pero es significativamente más flexible. Solo recuerda la regla de oro que un objeto debería llamar "nuevo" o realizar el procesamiento, pero no ambos. Para "llamar nuevo", reemplace con "resolver una referencia".
Esa no es realmente una clase singleton. Esa es una clase estática con miembros estáticos. Y sí, eso parece un buen enfoque.
Creo que JP Boodhoo incluso tiene un nombre para este patrón. El patrón Static Gateway .
Todo depende del uso. Usar el contenedor de esa manera se llama Patrón de Localizador de Servicio. Hay casos en los que no es una buena opción y casos en los que se aplican.
Si googleas el "patrón de localización de servicios", verás muchas publicaciones de blogs que dicen que es un antipatrón, pero no lo es. El patrón simplemente ha sido usado en exceso (/ abusado).
Para las aplicaciones típicas de la línea de negocio, no debe usar SL ya que oculta las dependencias. También tiene otro problema: no puede administrar el estado / duración si usa el contenedor raíz (en lugar de uno de sus tiempos de vida).
El localizador de servicios se adapta bien a la infraestructura. Por ejemplo, ASP.NET MVC utiliza Service Locator para poder resolver todas las dependencias de cada controlador.