请注意:我刚开始使用AutoFac来了解DI和IoC。
是否应该在控制器构造函数中初始化依赖注入?
这是怎么回事?
private IMyService iMyService;
public HomeController(IMyServices myService)
{
iMyService = myService;
}
与...不同
public IMyService iMyService = new MyService();
最后,似乎依赖性仍然存在。
编辑:修正了拼写错误,新的MyService();是新的IMyService();
答案 0 :(得分:3)
Dependency Injection意味着完全依赖注入。它没有说明初始化。例如。如果你正在注入Singleton的依赖项,那么它可以在你注入它之前很久就被初始化了。
您的第一个代码是通常的dependency injection via constructor。你的第二个代码不是依赖注入。实际上它对我来说看起来很奇怪 - 要么你试图创建接口实例,这是不可能的,要么你在这里命名不好。如果它只是错误的命名或拼写错误,那么第二个样本应该看起来像:
public IMyService iMyService = new MyServiceImplementation();
但你不是在这里注射任何东西。您只是创建依赖项实例(这使您的控制器耦合到依赖项实现)。
答案 1 :(得分:2)
编辑,依赖项总是“存在”但它被移到了类之外
请注意IMyServices
现在可以在与HomeController
相同的项目中定义
当MyService
完全属于另一个班级时。并且HomeController
的DLL可以在不知道你的MyService
dll有效地将它们解耦的情况下进行编译。
这是一个非常复杂的主题,您应该阅读一本关于它的书。阅读博客视频等并没有真正帮助。
这是一本好书。 http://www.amazon.com/Dependency-Injection-NET-Mark-Seemann/dp/1935182501这是一个伟大的视频讲座系列前5个视频关于DI一般 http://channel9.msdn.com/Blogs/mtaulty/Prism--Silverlight-Part-1-Taking-Sketched-Code-Towards-Unity
启动主要集中在组合根 http://blog.ploeh.dk/2011/07/28/CompositionRoot/
此处显示的模式为 CONSTRUCTOR INJECTION
https://softwareengineering.stackexchange.com/questions/177649/what-is-constructor-injection
答案 2 :(得分:2)
依赖注入并非易事 - 概念很简单,但理解它可能需要一些实践和研究。让我举一个使用DI的地方的例子,也许它会有意义(可能不是最好的例子,抱歉我想不出更好的ATM):
所以说你有以下课程:
public class MyAwesomeClass {
private readonly IConfig _config;
public MyAwesomeClass(IConfig config) {
_config = config;
}
public IEnumerable<string> GetFiltered() {
IEnumerable<string> results = _config.GetSettings();
// filter my results
return results.Where(x => x.StartsWith("awesome", StringComparison.OrdinalIgnoreCase));
}
}
现在,如果你要测试GetFiltered
,你可以注入IConfig
的假实现,并确保你的过滤器正常工作(你隔离你的代码与depdendencies )。你也可以通过暴露依赖关系来让反转控件并让你的班级用户来处理它们,你几乎都说 - “如果你想让我工作,我需要你给我一个IConfig
的实施,你要照顾它。“
以下是测试的样子
[Test]
public void GetsOnlyResultsContainingAwesome() {
var fakeConfig = new FakeConfig();
var awesome = new MyAwesomeClass(fakeConfig);
IEnumerable<string> results = awesome.GetFiltered();
Assert.AreEqual(2, results.Count());
}
以下是IConfig
public class FakeConfig : IConfig {
public IEnumerable<string> GetSettings() {
return new List<string> { "test1", "test2", "awesome1", "awesome2" };
}
}
我希望这是有道理的。对不起,如果我的例子不好,但我只想说明一点。
答案 3 :(得分:1)
你可以这么说。实际上,AutoFac,ninject等具有将接口与类绑定的功能。所以你需要先做到这一点。我的意思是说你需要创建一个类,你需要让AutoFac和ninject将它与接口绑定。
因此,当控制器寻找任何特定接口时,AutoFac和ninject将只创建该类的对象并将其分配给接口。就初始化而言,您可以在使用接口绑定类时初始化值。
答案 4 :(得分:1)
private IMyService iMyService;
public HomeController(IMyServices myService)
{
iMyService = myService;
}
在这种情况下,你只关心你需要什么(IMyServices)
public IMyService iMyService = new MyService();
但在这种情况下,你关心它将是什么(新的MyService())
设计课程时,你知道自己需要什么;
但是那将是什么,不是由你决定的,由谁使用你的班级决定