【问题标题】:Is this dependency injection? [duplicate]这是依赖注入吗? [复制]
【发布时间】:2019-02-25 23:49:04
【问题描述】:

如果我更改以下代码,这是否是依赖注入

class Needer
{
    Needed obj;
    AnotherNeeded obj2;

    public Needer()
    {
        obj = new Neede();
        obj2 = new AnotherNeede();
    }
}

到此代码

class Needer
{
    Needed obj;
    AnotherNeeded obj2;

    public Needer(Needed param1, AnotherNeeded param2)
    {
        obj = param1;
        obj2 = param2;
    }
}

【问题讨论】:

  • 这些例子都不是依赖注入。您应该在构造函数中使用接口/抽象作为参数,然后将这些参数值分配给您的字段/属性。依赖注入的重点是永远手动新建一个依赖。看看你的第二个例子,param1param2 永远不会去任何地方,你完全忽略它们......
  • 完全没有,这里连构造函数参数都没有赋值给变量
  • @maccettura 和 mbharanidharan88!伙计们请稍等……那是一个复制粘贴,从来没有打算这样做。我已经用正确措辞的代码更新了我的问题
  • 有趣的 cmets。是的,示例 2 在技术上是依赖注入,但采用接口比采用具体类型更好。

标签: c# dependency-injection


【解决方案1】:

第一个选项是通过在构造函数中新建依赖类来将依赖类与其依赖项紧密耦合。这使得单独测试该类非常困难(但并非不可能)

第二个选项遵循有时称为The Explicit Dependencies Principle

显式依赖原则指出:

方法和类应该明确要求(通常通过方法参数或构造函数参数)它们需要的任何协作对象才能正常运行。

也就是说,通常还建议让依赖类依赖于抽象,而不是具体化或实现问题。

因此,假设那些需要的类具有从它派生的接口/抽象,看起来像

class Needer {
    private readonly INeeded obj;
    private readonly IAnotherNeeded obj2;

    public Needer(INeeded param1, IAnotherNeeded param2) {
        obj = param1;
        obj2 = param2;
    }

    //...
}

这使得依赖类具有更大的灵活性,因为它将依赖类与实现问题解耦,从而更容易隔离测试类。

【讨论】:

    【解决方案2】:

    Robert C. Martin 在his SOLID design proposal 中描述了依赖注入。它基本上指出:

    • 高级模块不应依赖于低级模块。两者都应该依赖于抽象。

    • 抽象不应依赖于细节。细节应该取决于抽象。

    注意到该描述中经常使用的一个词? “抽象”。

    您在第二个示例中得到部分问题,您不再手动实例化类的实例,而是将它们传递给构造函数。但是,这会导致一个新的潜在问题,如果您需要某个类的不同 实现(例如“模拟”和“真实”服务),该怎么办。如果您的构造函数采用 abstractions 而不是具体的,您可以更改 IoC 配置中的实现。

    任何种类的服务或功能类通常都应该有一个抽象。这使您的代码更灵活、可扩展且更易于维护。所以要让你的第二个例子使用 true 依赖注入:

    class Needer
    {
        public INeeded obj { get; set; }
        public IAnotherNeeded obj2 { get; set; }
    
        public Needer(INeeded param1, IAnotherNeeded param2)
        {
            obj = param1;
            obj2 = param2;
        }
    }
    

    现在你可以拥有各种实现

    public class MockNeeded : INeeded
    
    public class ApiNeeded : INeeded
    

    等等等等

    【讨论】:

      【解决方案3】:

      第二个例子是DI(依赖注入)。 DI 通常与 IoC(控制反转)一起使用 它会根据一些配置为您创建依赖项。 看看autofac。 autofac

      【讨论】:

        【解决方案4】:

        注射不会自行发生。

        相反,应该有某种工厂来生成对象并使用依赖解析器(如果可用)。

        例如,MVC.NET 框架就是那种“工厂”,当它创建Controller 类的实例时,它使用DependencyResolver.Current 属性来填充构造函数参数。

        【讨论】:

        • 你说的是一个 IoC 容器,它不是依赖注入,只是一个促进者。
        猜你喜欢
        • 1970-01-01
        • 2011-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-22
        • 1970-01-01
        相关资源
        最近更新 更多