如果我更改下面的代码,这是依赖注入吗?
catch
此代码
class Needer
{
Needed obj;
AnotherNeeded obj2;
public Needer()
{
obj = new Neede();
obj2 = new AnotherNeede();
}
}
答案 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
属性来填充构造函数参数。