c# - 依赖注入(inject)——何时使用属性注入(inject)

标签 c# dependency-injection ioc-container

我有一个类有这样的构造函数:

    private string _someString;
    private ObjectA _objectA;
    private ObjectB _objectB;
    private Dictionary<Enum, long?> _dictionaryA;
    private Dictionary<Tuple<Enum,long?>, long?> _dictionaryB; 

    public SomeDiClass(string someString)
    {
        _someString = someString;

        _objectA = new ObjectA();
        _objectB = new ObjectB();

        _dictionaryA = new Dictionary<Enum, long?>();
        _dictionaryB = new Dictionary<Tuple<Enum, long?>, long?>();
    }

我想从这个构造函数中创建依赖项。在第一步中,我会将 ObjectA 和 B 依赖项移动到构造函数参数,以通过构造函数注入(inject)来注入(inject)它们。我想为此目的使用一个 IoC 容器,这就是我目前坚持的地方。问题是如何处理 someString 和字典。我需要将它们注入(inject)类,因为字典的内容将是单元测试的重要组成部分。 通过属性注入(inject)注入(inject)字符串和字典是否是个好主意(我在其他类中不需要它们),所以我最终会得到这样的东西?:

    private ObjectA _objectA;
    private ObjectB _objectB;

    public string SomeString { get; set; }
    public Dictionary<Enum, long?> DictionaryA { get; set; }
    public Dictionary<Tuple<Enum, long?>, long?> DictionaryB { get; set; }

    public SomeDiClass(ObjectA objectA, ObjectB objectB)
    {
        _objectA = objectA;
        _objectB = objectB;
    }

是否有解决此类问题的最佳实践?

最佳答案

依赖注入(inject)不是最终目标,而是针对一组特定问题的解决方案。例如,依赖注入(inject)可以轻松替换单元测试的抽象并使您的应用程序更加灵活,因为您可以交换、修饰和拦截依赖项而无需更改消费类。可以在这个免费提供的 chapter 1 中找到对依赖注入(inject)的一个很好的介绍。书的Dependency Injection Principles, Practices, and Patterns (DIPP&P),我与人合着。

这并不意味着您应该注入(inject)一个类所具有的每个 依赖项,因为它必须帮助您使类更易于测试并使系统更易于维护。因此,您必须问问自己,从测试的角度来看,从外部注入(inject)这些字典是否有帮助,或者是否有助于使您的应用程序更加灵活。要很好地掌握要注入(inject)什么以及不注入(inject)什么,您应该了解易变和稳定依赖关系的概念,可以在 section 1.3 中阅读这些概念。 DIPP&P 第 1 章。

从测试或可维护性的角度来看,它是否有帮助是一个很难回答的问题,因为您的问题不够详细。但这里有一些提示:

您通常唯一想注入(inject)到类中的是服务和配置值。

  • 服务是提供“服务”的某种契约/抽象/接口(interface)。这通常意味着该服务将代表您做一些事情,例如计算价格、与数据库通信、缓存值、返回系统时间或格式化您的硬盘:)

  • 配置值就是它的本来面目;只是一个值。但是您需要注入(inject)它——它不能硬编码到类中,并且您不希望类本身从 ConfigurationManager 中获取值,例如,因为那样会创建一个隐藏的依赖项(在 Configurationmanager 上),这会使类更难测试。

其他东西,例如原语、消息、DTO、集合类型和实体,以及任何其他不提供任何服务(业务逻辑)并且不妨碍单元测试的东西,都不必是抽象,因此不必注入(inject)(实际上是 shouldn't be injected through the constructor or property )。在您的情况下,字典是 SomeDiClass 类的内部状态的一部分,而不是您的类所依赖的服务。

另一方面,如果这些字典被其他服务重用,则必须注入(inject)这些字典。但是你永远不想直接注入(inject)这样的字典本身,因为字典本身不是服务。相反,您需要围绕它们创建一个抽象;隐藏该字典的详细信息并为应用程序提供围绕它的服务的东西。

关于c# - 依赖注入(inject)——何时使用属性注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18779894/

相关文章:

c# - EF 核心 "No DbContext named xxx was found'

c# - 使用匿名方法

c# - 按字母顺序排列数组

javascript - 使用 require.js 和 testr.js 启动并运行

c# - Autofac:使用 in 和 out 类型参数解析变体类型

c# - 声音播放器 : How to select Output device?

Scala:使用依赖注入(inject)协调类型类

c# - ASP.NET Core - 使用 [FromServices] 属性可能会带来哪些挑战或问题?

c# - 如何在 SimpleIOC 中注册包含参数的类实例

java - 从外部 bean 注入(inject) bean 属性