这是依赖注入吗?

时间:2018-09-21 14:30:44

标签: c# dependency-injection

如果我更改下面的代码,这是依赖注入吗?

catch

此代码

class Needer
{
    Needed obj;
    AnotherNeeded obj2;

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

4 个答案:

答案 0 :(得分:3)

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

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

  • 抽象不应依赖细节。详细信息应取决于抽象。

注意到该描述中使用了很多单词吗? “ 抽象”。

在第二个示例中,您可以得到问题的一部分,您不再手动实例化该类的实例,而是将它们传递给构造函数。但是,这导致了一个新的潜在问题,如果您需要某个类的不同实现(例如“模拟”和“真实”服务),该怎么办。如果您的构造方法使用了抽象而不是具体的方法,则可以更改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

等,等等

答案 1 :(得分:2)

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

第二个选项后面是有时称为The Explicit Dependencies Principle

  

显式依赖原则规定:

     

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

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

因此,假设那些需要的类具有从其派生的接口/抽象,将类似于

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

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

    //...
}

由于从属类将实现类与实现问题分离开来,因此可以提供更大的灵活性,从而使隔离类的测试更加容易。

答案 2 :(得分:0)

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

答案 3 :(得分:-1)

注射不会自己发生。

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

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