Достижение DI без сторонних фреймворков - PullRequest
4 голосов
/ 14 февраля 2012

Я пишу плагин как часть архитектуры плагинов. Способ создания плагинов - это отражение и CreateInstance. Поэтому конструктор по умолчанию называется. Этот код я не могу коснуться, и я пытаюсь найти разумный способ использовать DI без возможности использовать каркас.

Мне кажется, у меня есть 3 варианта:

i) Бедняжка (PMDI)

ii) Заводская модель

iii) TinyIOC или аналогичный (один файл cs, который обрабатывает DI)

Я начал смотреть на PMDI, но затем зависимость нуждалась в другой зависимости, поэтому у меня получилось нечто похожее на это, что уродливо и может ухудшиться:

public MyMainPluginClass() : this(new Repo(new Logger()))
{

}

public MyMainPluginClass(IRepo repo)
{

}

Затем я перешел к идее фабричного шаблона, но не смог найти приличный демонстрационный код. Я предполагаю, что у меня было бы что-то вроде этого:

public static FactoryUtility
{
  public static IRepo GetRepo()
  {
    return new Repo(GetLogger());
  }

  public static ILogger GetLogger()
  {
    return new Logger();
  }
}

    public MyMainPluginClass() : this(FactoryUtility.GetRepo())
    {

    }

    public MyMainPluginClass(IRepo repo)
    {

    }

Так это будет выглядеть?

Затем я наткнулся на TinyIOC , который является одним классом, который выполняет всю регистрацию зависимостей, но я считаю, что его необходимо настроить в Program.cs, которого у меня нет в библиотеке классов. Если у кого-то есть опыт использования этого, его можно использовать так:

    public MyMainPluginClass()
    {
       var container = TinyIoCContainer.Current;
       container.AutoRegister();
       var implementation = container.Resolve<IRepo>();

       MyMainPluginClass(implementation);
    }

    public MyMainPluginClass(IRepo repo)
    {

    }

Существуют ли какие-либо альтернативные подходы для достижения DI без использования сторонней библиотеки, и если нет, какой подход будет выбран из вышеперечисленных?

ПРИМЕЧАНИЕ: Приведенный выше код не был скомпилирован и представляет собой лишь идею того, что, я думаю, будет работать. Пожалуйста, опубликуйте исправления, если они действительны.

Ответы [ 3 ]

2 голосов
/ 14 февраля 2012

Поскольку вы используете .NET 4, вы можете рассмотреть возможность использования MEF, поскольку он встроен в сам фреймворк.Это выглядит как довольно простой DI, с которым MEF хорошо справляется, поскольку он предназначен в основном для расширяемости.

Подробнее см. На странице Узнать больше на сайте MEF CodePlex .

1 голос
/ 14 февраля 2012

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

public MyMainPluginClass() : this(FactoryUtility.SetupIOC())
{

}

public MyMainPluginClass(IRepo repo)
{

}

public static class FactoryUtility
{
    private static bool Initialized  = false;

    public static IRepo SetupIOC()
    {
        var container = TinyIoCContainer.Current;

        if (!Initialized)
        {
            container.AutoRegister(new[] { Assembly.GetExecutingAssembly() });

            Initialized = true;
        }

        var result = container.Resolve<IRepo>();

        return result;
    }
}
0 голосов
/ 14 февраля 2012

Если я абсолютно не хочу добавлять зависимость к контейнеру DI, мне нравится использовать мой собственный TinyIOC (извините за имя, я не знал, что он был взят), который для небольших проектов дает мне ту же семантикукак с использованием контейнера, но с тактовой частотой ниже 200 LOC.

Если вам интересно, вот код: https://gist.github.com/ad7608e2ae10b0f04229

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...