【发布时间】:2016-03-24 08:56:16
【问题描述】:
我相信我对依赖注入有足够的了解,可以开始使用它,但是我无法理解 IOC 容器与服务位置,以及如何使用容器构造我的对象。
给定:
public interface IFooService
{
void DoSomethingFooey();
}
public class FooService : IFooService
{
readonly IBarService _barService;
public FooService(IBarService barService)
{
this._barService = barService;
}
public void DoSomethingFooey()
{
// some stuff
_barService.DoSomethingBarey();
}
}
public interface IBarService
{
void DoSomethingBarey();
}
public class BarService : IBarService
{
readonly IBazService _bazService;
public BarService(IBazService bazService)
{
this._bazService = bazService;
}
public void DoSomethingBarey()
{
// Some more stuff before doing ->
_bazService.DoSomethingBazey();
}
}
public interface IBazService
{
void DoSomethingBazey();
}
public class BazService : IBazService
{
public void DoSomethingBazey()
{
Console.WriteLine("Blah blah");
}
}
如果没有 IOC 容器,我将不得不在构建时提供所有依赖项,如下所示:
public void DoStuff()
{
// Without a container, I would have to do something yucky like:
FooService fs = new FooService(
new BarService(
new BazService()
)
);
// or
BazService bazService = new BazService();
BarService barService = new BarService(bazService);
FooService fooService = new FooService(barService);
}
通过以这种 DI 方式构建我的类,我似乎收获了很多,因为我现在可以独立测试我的类,而在使用 DI 之前我真的不能。
但是根据我正在阅读的有关执行 DI 的“正确方法”的内容,我会使用 Unity 或 StructureMap 之类的 IOC 容器......但我还没有找到我需要了解如何开始的确切内容。
我假设我的容器看起来像这样:
var container = new Container(_ =>
{
_.For<IFooService>().Use<FooService>();
_.For<IBarService>().Use<BarService>();
_.For<IBazService>().Use<BazService>();
});
取自以下示例:http://structuremap.github.io/quickstart/
基于上面的例子,我不确定包含var container... 的方法的签名是什么样的,或者它是如何被调用并保持在范围内的。或许更重要的是如何利用容器实际构造对象。
如果我想创建FooService 的实例(然后是BarService 和BazSerivce),我的DoStuff() 现在会是什么样子?
以前是:
public void DoStuff()
{
// Without a container, I would have to do something yucky like:
FooService fs = new FooService(
new BarService(
new BazService()
)
);
// or...
}
但是现在使用我的容器会是什么样子?我的方法如何知道在哪里寻找我的容器?
希望我在某种程度上走在正确的轨道上,但如果我不是,请告诉我,以及我缺少什么。
【问题讨论】:
-
你缺少的是Composition Root的概念。
-
不要被那些说使用 IOC 容器是“进行 DI 的正确方法”的人所迷惑。你可以使用容器,也可以练习Pure DI。两者都有其价值和起伏。提问when to use a container总是好的。
-
@Steven 我目前通过更新我的对象所做的事情会被视为“纯 DI”吗?或者这是否也需要一个组合根?这些文章虽然内容丰富,但至少对我来说仍然很抽象,我想得到一些更具体的东西。
-
使用 Pure DI,您可以在组合根中构建对象图。
标签: c# dependency-injection inversion-of-control ioc-container structuremap