Как я могу эмулировать модули / установщики / реестры с помощью простого инжектора - PullRequest
12 голосов
/ 24 января 2012

В Autofac есть модули, в Windsor есть установщики и реестры StructureMap ... с простым инжектором, как я могу упаковать логику конфигурации в повторно используемые классы?

Я пробовал:

public interface IModule { }

public class FooModule : IModule
{
    public FooModule(SimpleInjector.Container container)
    {
        container.RegisterSingleton<IBar, Bar>();
        container.RegisterSingleton<IFoo, Foo>();
    }
}

И я использую его в корне композиции:

public static void Main(string[] args)
{
    var container = new SimpleInjector.Container();
    container.RegisterCollection<IModule>(new FooModule(container));
    ...
}

Однако FooModule зависит от контейнера и, возможно, не очень хорошая практика ... см http://code.google.com/p/autofac/wiki/BestPractices:

Если компоненты зависят от контейнера, посмотрите, как они используют контейнер для извлечения служб и добавления этих служб к компоненту (зависимость вместо этого вводятся аргументы конструктора.

1 Ответ

14 голосов
/ 24 января 2012

Функция 'module' намеренно исключена из базовой библиотеки Simple Injector, но есть пакет SimpleInjector.Packaging NuGet , который позволяет вам сделать это.«Пакет» - это термин, который использует Simple Injector.Однако эта библиотека - не более чем один IPackage интерфейс и два метода расширения.Вы можете достичь того же самого, написав такой код:

Пакет:

public static class BootstrapperPackage
{
    public static void RegisterServices(Container container)
    {
        container.Register<IBar, Bar>(Lifestyle.Scoped);
        container.Register<IFoo, Foo>(Lifestyle.Singleton);            
    }
}

В корне вашей композиции:

public static void Main(string[] args)
{
    var container = new SimpleInjector.Container();

    BootstrapperPackage.RegisterServices(container);

    ...
}

Разница с Пакет SimpleInjector.Packaging NuGet состоит в том, что этот пакет определяет интерфейс для вас и позволяет динамически загружать несколько пакетов в одну строку:

public class BusinessLayerPackage : IPackage
{
    public void RegisterServices(Container container)
    {
        container.Register<IBar, Bar>(Lifestyle.Scoped);
        container.Register<IFoo, Foo>(Lifestyle.Singleton);            
    }
}

public static void Main(string[] args)
{
    var container = new SimpleInjector.Container();

    container.RegisterPackages(AppDomain.CurrentDomain.GetAssemblies());
}

Однако, если вам действительно не нужен динамическийзагрузка с использованием статических методов (как показано выше) является предпочтительной, поскольку она имеет следующие преимущества:

  • Делает загрузочные модули очень явными и обнаруживаемыми.
  • Позволяет легко выбирать, какие модулизагружать, а что нет.
  • Облегчает передачу дополнительных значений в методы RegisterServices, такие как значения конфигурации, которые требуются для такого модуля.Это предотвращает жесткую зависимость модуля от системы конфигурации.

Для получения дополнительной информации, пожалуйста, прочитайте this .

...