Duket se ka një stigmë mbi SO në lidhje me përdorimin e Singletons. Nuk e kam blerë kurrë personalisht, por për hir të mendjes së hapur po përpiqem të provoj konceptet e IoC si alternativë, sepse sinqerisht jam i mërzitur me punën time të përditshme dhe do të doja të provoja diçka ndryshe. Më falni nëse interpretimi im i koncepteve të IoC është i pasaktë ose i gabuar.
Këtu është situata: Unë po ndërtoj një server të thjeshtë ueb bazuar në HttpListener
në një shërbim Windows që përdor një model shtesë për të përcaktuar se si duhet të trajtohet një kërkesë bazuar në URL-në e kërkuar (ashtu si çdokush tjetër që pyet për HttpListener
). Qasja ime për të zbuluar shtojcat është të kërkoj një drejtori të konfiguruar për asambletë të zbukuruara me një HttpModuleAssemblyAttribute
. Këto asamble mund të përmbajnë 0 ose më shumë IHttpModule
fëmijë të cilët përveç kësaj janë zbukuruar me një HttpModuleAttribute
që përdoret për të specifikuar emrin e modulit, versionin, përshkrimin e lexueshëm nga njeriu dhe informacione të tjera të ndryshme. Diçka si:
[HttpModule(/*Some property values that matter */)]
public class SimpleHttpModule : IHttpModule
{
public void Execute(HttpListenerContext context)
{
/* Do Something Special */
}
}
Kur zbulohet një HttpModule
, unë zakonisht do ta shtoja atë në një objekt Dictionary<string, Type>
, i cili qëllimi i vetëm është të mbajë gjurmët se për cilat module dimë. Ky fjalor zakonisht do të jetonte në varietetin tim të një Singleton që merr personalitetin e një Singleton ACE (një trashëgimi nga ditët e mia në C++ ku mësova për Singletons).
Tani ajo që unë po përpiqem të zbatoj është diçka e ngjashme duke përdorur (të kuptuarit tim) konceptet e përgjithshme të IoC. Në thelb ajo që kam është një koleksion AppService
ku IAppService
përkufizohet si:
public interface IAppService : IDisposable
{
void Initialize();
}
Dhe shtojca ime AppService
do të dukej diçka si kjo:
[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
}
Pastaj gjatë shërbimit OnStart
unë instantoj një shembull të AppServices
i cili është i njohur lokalisht, por i kalohet konstruktorit të të gjitha shtojcave të instancuara:
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);
}
}
Zbatimi i metodës sonë dikur të vetme bëhet një zbatim abstrakt + një konstruktor për fëmijën:
[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 */
}
}
Dhe çdo akses në shërbimet e aplikacioneve të përdorura zakonisht bëhet:
var plugType = appServices["Plugins"][plugName];
më mirë se:
var plugType = PluginManager.Instance[plugName];
A më mungon ndonjë koncept bazë IoC këtu që do ta thjeshtonte të gjithë këtë apo ka vërtet një përfitim nga i gjithë ky kod shtesë? Në botën time, Singletonët janë krijesa të thjeshta që lejojnë kodin përgjatë një programi të aksesojë informacionin e nevojshëm (relativisht statik) (në këtë rast llojet).
Për të shtruar pyetjet më qartë:
- A është ky një zbatim i vlefshëm i një Factory Singleton të përkthyer në konceptet IoC/DI?
- Nëse është, ku është kthimi/përfitimi për kodin shtesë që kërkohet dhe vendosja e një API në dukje më të ngathët?