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

本文关键字:安装 程序 注册表 模块 模拟 何使用 Simple Injector | 更新日期: 2023-09-27 18:21:26

Autofac有模块,Windsor有安装程序和StructureMap注册表。。。使用SimpleInjector,如何将配置逻辑打包到可重用类中?

我试过:

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

我在Composition Root:中使用了它

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:

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

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

Simple Injector核心库中故意省略了一个"module"功能,但有一个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);            
    }
}

在你的作文根:

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方法,例如此类模块所需的配置值。这可以防止模块对配置系统产生硬依赖

欲了解更多信息,请阅读本文。