c# - 如何使用简单注入(inject)器模拟模块/安装程序/注册表

标签 c# .net dependency-injection ioc-container simple-injector

Autofac 有模块,Windsor 有 Installers 和 StructureMap Registries ... 使用 Simple Injector 如何将配置逻辑打包到可重用的类中?

我试过:

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 :

If components have a dependency on the container, look at how they're using the container to retrieve services, and add those services to the component's (dependency injected) constructor arguments instead.

最佳答案

Simple Injector 核心库中故意遗漏了一个“模块”功能,但有一个 SimpleInjector.Packaging NuGet package这让你可以做到这一点。 “包”是 Simple Injector 使用的术语。然而,这个库只不过是一个 IPackage 接口(interface)和两个扩展方法。您可以通过编写如下代码来实现相同的目的:

一个包:

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 package的区别是这个包为你定义了一个接口(interface),并允许你在一行中动态加载多个包:

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 .

关于c# - 如何使用简单注入(inject)器模拟模块/安装程序/注册表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8983843/

相关文章:

azure - 启动在本地使用 IHttpClientFactory 依赖项注入(inject)的 Azure Function 项目时出现 FileNotFoundException

java - 是否可以使用 Guice 限制类型层次结构扫描?

c# - 我应该在哪个级别应用依赖注入(inject)? Controller 还是域?

c# - 如何将外键从一个 View 传递到另一个 View ?

c# - 如何使用 C# 检测 WPF 中 UI 线程何时启动和停止处理?

c# - MongoDB C# 聚合计数

c# - ListView OwnerDraw 的默认实现

.net - .NET 中是否有多线程 TCP 服务器套接字?

c# - 列出目录中的文件夹,其 id 不是 Google Drive API v3 和 C# 中的特定值

c# - 数据绑定(bind)到 MvvMCross 中的非 ViewModel 属性