c# - 配置设置和 IoC

标签 c# .net dependency-injection architecture inversion-of-control

我使用 IoC (DI) 方法并且通常有参数,这些参数由最低层(数据库层等)从配置设置(即连接字符串、静态值等)中读取。最好的方法是什么?

  1. 直接在这个最底层读取,即:

    string sendGridApiKey = ConfigurationManager.AppSettings["SendGridApiKey"];
    

它可以工作,但还需要将此键添加到单元测试项目的配置文件中。另外,汇编依赖于配置文件

  1. 在最高层(即网络应用程序)读取它并作为所有层的参数抛出?它会工作,但所有中间层都会获得未使用的参数(因此,它们将取决于未使用的事物)。

还有一个问题是,最低层的不同实现可能需要不同的参数。 IE。 SendMail1 可以要求 SMTP/login/password,但是 SendMail2 可以只要求 ApiKey,但是 SendMail1 和 SendMail2 应该实现相同的接口(interface)。因此,使用方法 #2 会造成困难

最佳答案

您概述的两种方法都效果不佳 - 首先(读取服务中的配置)会阻止您提到的单元测试,其次(从顶层传递配置)需要顶层了解每个服务的所有可能实现。

我喜欢依赖于 DI 容器的配置存储和为每个接口(interface)注册的对象类型的知识的方法:

  • 在注册时传递配置——也就是说,如果容器支持注册工厂方法,那么工厂方法可以读取配置,而不是调用具体服务的特定构造函数

    // constructor: publc ConcreteServiceX(int setting1, string setting2)...
    container.RegisterFactory<IServiceX>(
        container => return new ConcreteServiceX(42, ReadSetting("X"));
    
  • 将容器中的每个服务的配置注册为类/接口(interface)

    // constructor: publc ConcreteServiceX(IConcreteServiceXSettings settings)...
    container.RegisterType<IService,ConcreteServiceX>();
    container.RegisterInstance<IConcreteServiceXSettings>(
         new ConcreteServiceXSettings(42, ReadSetting("X"));
    

这两种方法都将配置系统的知识本地化到一个地方(容器配置),并允许更轻松地对每个服务(不依赖于配置存储类型)以及更高级别的对象(不需要知道服务的任何设置)进行单元测试.


注意:示例使用类 Unity 语法,采用您选择的容器

关于c# - 配置设置和 IoC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35530725/

相关文章:

c# - 如何在C#中创建带有特殊字符的字符串

c# - 如何使用 MSBuild 和 IIExpress.exe 从命令行构建和运行 .NET Framework MVC 项目

c# - 如何在 C# (.NET) 中将文件上传到 SFTP 服务器?

Angular 2 Renderer2 - 它是如何工作的

java - 在不使用 Java 中的任何 DI 框架的情况下,实际上有可能做好 TDD(或 BDD)吗?

c# - 是否有 .NET Framework 方法来解析电子邮件 (MIME)?

c# - 如何在 Windows 窗体中打开特定选项卡

c# - 在 C# 中替换字符串

c# - 扫描图像 OpenCV 上的文档检测

java - 使用 Guice 的模块化 Java 插件系统