Подтвердить что ты не робот

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

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

Я пробовал:

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:

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

4b9b3361

Ответ 1

Функция 'module' намеренно исключена из основной библиотеки Simple Injector, но есть SimpleInjector.Packaging NuGet package, который позволяет вы это сделаете. "Пакет" - это термин "Простой инжектор". Однако эта библиотека представляет собой не более чем один интерфейс 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.