如何使用Simple Injector模拟模块/安装程序/注册表

o3o*_*o3o 13 .net c# dependency-injection ioc-container simple-injector

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>();
    }
}
Run Code Online (Sandbox Code Playgroud)

我在Composition Root中使用它:

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

但是,FooModule取决于容器,可能不是一个好的做法...请参阅http://code.google.com/p/autofac/wiki/BestPractices:

如果组件依赖于容器,请查看它们如何使用容器来检索服务,并将这些服务添加到组件(依赖注入)构造函数参数中.

Ste*_*ven 15

故意将"模块"功能排除在Simple Injector核心库之外,但是有一个SimpleInjector.Packaging NuGet包允许您执行此操作.'Package'是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);            
    }
}
Run Code Online (Sandbox Code Playgroud)

在你的作文根:

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

    BootstrapperPackage.RegisterServices(container);

    ...
}
Run Code Online (Sandbox Code Playgroud)

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());
}
Run Code Online (Sandbox Code Playgroud)

但是,如果您不需要动态加载,则首选使用静态方法(如上所示),因为它具有以下优点:

  • 使加载模块非常明确且可被发现.
  • 可以轻松选择要加载哪些模块,哪些模块不加载.
  • 可以轻松地将额外值传递给RegisterServices方法,例如此类模块所需的配置值.这可以防止模块对配置系统产生硬依赖性.

有关更多信息,请阅读此内容.