Parece haber un estigma en SO con respecto al uso de Singletons. Nunca lo he aceptado personalmente, pero en aras de la mentalidad abierta intento dar una oportunidad a los conceptos de IoC porque estoy francamente aburrido de mi trabajo diario y me gustaría probar algo diferente. Perdóname si mi interpretación de los conceptos de la IoC es incorrecta o está mal dirigida.Ventaja de IoC sobre mi Factory Singleton
Aquí está la situación: estoy construyendo un simple servidor web basado en HttpListener
en un servicio de Windows que utiliza un modelo de complemento para determinar cómo debe manejarse una solicitud basada en la URL solicitada (como todos los que preguntan HttpListener
). Mi enfoque para descubrir los complementos es consultar un directorio configurado para conjuntos decorados con un HttpModuleAssemblyAttribute
. Estos ensambles pueden contener 0 o más IHttpModule
niños que además están decorados con un HttpModuleAttribute
utilizado para especificar el nombre del módulo, la versión, la descripción legible por el ser humano y otra información. Algo así como:
[HttpModule(/*Some property values that matter */)]
public class SimpleHttpModule : IHttpModule
{
public void Execute(HttpListenerContext context)
{
/* Do Something Special */
}
}
Cuando se descubre un HttpModule
que normalmente se sumaría a un objeto Dictionary<string, Type>
que es único propósito es mantener un registro de los módulos que conocemos. Este diccionario típicamente viviría en mi variedad de Singleton que toma la personalidad de ACE style Singleton (un legado de mis días en C++ donde aprendí sobre Singletons).
Ahora lo que estoy tratando de implementar es algo similar usando (mi entendimiento de) conceptos generales de IoC. Básicamente lo que tengo es una colección AppService
donde IAppService
se define como:
public interface IAppService : IDisposable
{
void Initialize();
}
Y mi plug-in AppService
sería algo como:
[AppService("Plugins")]
internal class PluginAppService : IAppService, IDictionary<string, Type>
{
/* Common IDictionary Implementation consisting of something like: */
internal Type Item(string modName)
{
Type modType;
if (!this.TryGetValue(modName, out modType)
return null;
return modType;
}
internal void Initialize()
{
// Find internal and external plug-ins and add them to myself
}
// IDisposable clean up method that attempts to dispose all known plug-ins
}
A continuación, durante el servicio OnStart
que se crea una instancia de AppServices
cuales es conocido localmente pero se transfiere al constructor de todos los complementos instanciados:
public class AppServices : IDisposable, IDictionary<string, IAppService>
{
/* Simple implementation of IDictionary */
public void Initialization()
{
// Find internal IAppService implementations, instantiate them (passing this as a constructor parameter), initialize them and add them to this.
// Somewhere in there would be something like
Add(appSvcName, appSvc);
}
}
Nuestra implementación del método, una vez sola se convierte en una implementación abstracta + un constructor en el niño:
[HttpModule(/*Some property values that matter */)]
public abstract class HttpModule : IHttpModule
{
protected AppServices appServices = null;
public HttpModule(AppServices services)
{
appServices = services;
}
public abstract void Execute(HttpListenerContext context);
}
[HttpModule(/*Some property values that matter */)]
public class SimpleHttpModule : HttpModule
{
public SimpleHttpModule(AppServices services) : base(services) { }
public override void Execute(HttpListenerContext context)
{
/* Do Something Special */
}
}
Y cualquier acceso a los servicios de aplicaciones de uso común se convierte en:
var plugType = appServices["Plugins"][plugName];
en lugar de:
var plugType = PluginManager.Instance[plugName];
¿Me falta aquí algún concepto básico de IoC que simplifique todo esto o hay realmente un beneficio para todo este código adicional? En mi mundo, Singletons son criaturas simples que permiten que el código de un programa acceda a la información necesaria (relativamente estática) (en este caso, tipos).
plantear la pregunta de manera más explícita:
- ¿Es esta una aplicación válida de un Singleton fábrica traducido a conceptos IOC/DI?
- En caso afirmativo, ¿dónde está la recuperación/beneficio del código adicional requerido y la imposición de una API aparentemente más torpe?
Probablemente no recibas la respuesta que estás buscando porque tu pregunta es demasiado vaga (a pesar de ser tan larga). Realmente debería figurar EXACTAMENTE qué pregunta quiere que se responda y preguntar. –
Creo que la reacción general contra los singletons se debe a que es un método para introducir el estado global en una aplicación, lo que va en contra del diseño orientado a objetos. También suelen ser difíciles de probar por unidad. –
@DBM: ¿El estado global es contrario a OOP? ¿Cómo es eso? En general, es un enfoque aceptado en C++ (que también es OO). –