Преимущество IoC над моим Factory Singleton

Похоже, на SO есть клеймо в отношении использования синглтонов. я лично никогда не покупался на это, но ради непредубежденности я пытаюсь попробовать концепции IoC в качестве альтернативы, потому что мне откровенно скучно моя повседневная работа и я хотел бы попробовать что-то другое. Простите меня, если моя интерпретация Концепции IoC неверны или ошибочны.

Вот ситуация: я создаю простой веб-сервер на основе HttpListener в службе Windows, который использует модель подключаемых модулей для определения того, как запрос sh может обрабатываться на основе запрошенного URL (как и все, кто спрашивает о HttpListener ). Мой подход к обнаружению подключаемых модулей состоит в том, чтобы запросить настроенный каталог для сборок, украшенных HttpModuleAssemblyAttribute .Эти сборки могут содержать 0 или более IHttpModule дочерних, которые, кроме того, украшены HttpModuleAttribute , используемым для указания имени модуля, версии, удобочитаемого описания и другой другой информации. Что-то вроде:

[HttpModule(/*Some property values that matter */)]
public class SimpleHttpModule : IHttpModule
{
    public void Execute(HttpListenerContext context)
    {
        /* Do Something Special */
    }
}

Когда обнаруживается HttpModule , я обычно добавляю его к объекту Dictionary , единственная цель которого - отслеживать, о каких модулях мы знаем . Этот словарь, как правило, находится в моей разновидности синглтона, который принимает образ синглтона в стиле ACE (наследие от моих дней C ++, когда я узнал о синглтонах).

Сейчас я пытаюсь реализовать нечто подобное, используя (мое понимание) общие концепции IoC.В основном у меня есть коллекция AppService , где IAppService определяется как:

public interface IAppService : IDisposable
{
    void Initialize();
}

И мой плагин AppService будет выглядеть примерно так:

[AppService("Plugins")]
internal class PluginAppService : IAppService, IDictionary
{
    /* 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
}

Тогда во время обслуживания OnStart Я создаю экземпляр AppServices , который известен локально, но передается конструктору всех созданных экземпляров подключаемых модулей:

public class AppServices : IDisposable, IDictionary
{
    /* 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);
    }
}

Наша единственная реализация метода становится абстрактной реализацией + конструктор дочернего элемента:

[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 */
    }
}

И любой доступ к часто используемым службам приложений становится:

var plugType = appServices["Plugins"][plugName];

, а не:

var plugType = PluginManager.Instance[plugName];

Мне не хватает здесь какой-то базовой концепции IoC, которая упростила бы все это, или действительно есть преимущества для всех этот дополнительный код? В моем мире синглтоны - это простые существа, которые позволяют коду программы получать доступ к необходимой (относительно статической) информации (в данном случае - к типам).

Чтобы задать вопросы более подробно:

  1. Является ли это допустимой реализацией Factory Singleton, переведенной на концепции IoC / DI?
  2. Если да, то где окупаемость / выгода от необходимого дополнительного кода и введения кажущийся более неуклюжим API?

9
задан M.Babcock 31 January 2012 в 13:34
поделиться