【发布时间】:2011-03-25 00:16:24
【问题描述】:
我听说人们谈论 IoC 中的子容器,当我在谷歌上搜索它时,我回到了这里,这些问题让我想知道它们最初是什么。
什么是 IoC 子容器以及它们是如何使用的?
【问题讨论】:
标签: c# .net dependency-injection ioc-container
我听说人们谈论 IoC 中的子容器,当我在谷歌上搜索它时,我回到了这里,这些问题让我想知道它们最初是什么。
什么是 IoC 子容器以及它们是如何使用的?
【问题讨论】:
标签: c# .net dependency-injection ioc-container
该术语没有单一的定义 - 在一个容器中实现为“子容器”的内容通常在另一个容器中具有完全不同的逻辑功能。
在 Autofac 和一些类似的容器中,“子容器”(从 v2 开始,只是一个“生命周期范围”)是一种创建生命周期短于“父”容器的相关组件集的方法,因此依赖关系仅从子到父解析,从不反过来。
其他容器有不同的实现,有些允许依赖解析双向进行(至少在我的理解中)。您正在使用的特定容器是获得更权威回答此问题的重要额外信息。
希望这会有所帮助!
【讨论】:
IoC - 或控制反转 - 是一种让您的类依赖于服务和其他类的方法,而实际上并不知道如何实例化它们并且只知道如何使用它们。考虑以下示例:
public class MyService
{
public void DoSomething()
{
Logger l = new Logger(); // let's assume this class exists, and it logs stuff
l.Info("Some info logmessage");
}
}
在这里我们将调用该服务:
public class MyProgram {
public MyProgram()
{
MyService myService = new MyService();
myService.DoSomething();
}
}
现在,通过依赖注入或 IoC,我们可以颠倒日志记录的职责。简而言之,这意味着MyService 不应该真正知道如何实例化记录器,但它应该知道如何使用它。
假设Logger 类实现了一个名为ILog 的接口,它只包含方法void Info(string s)
然后我们可以将 MyService 类重构为:
public class MyService
{
ILog _logger;
public MyService(ILog logger)
{
_logger = logger;
}
public void DoSomething()
{
_logger.Info("Some info logmessage");
}
}
这意味着我们也必须重构MyProgram:
public class MyProgram {
public MyProgram()
{
ILog logger = new Logger(); // instanciate it here instead.
MyService myService = new MyService(logger);
myService.DoSomething();
}
}
这基本上是控制反转,但是当我们开始谈论依赖注入时,这一切都可以自动化。假设我们想使用 Ninject 进行注入。我不会在这里写代码示例,但基础是 Ninject 将被设置为知道当某些类请求 ILog 接口时,我们应该返回 Logger 类。
这使我们能够轻松更改我们想要为不同接口使用的实现类型 - 也提高了可测试性。
我会在 tekpub 上推荐这个简短的免费视频,它将引导您了解使用 Ninject 进行 IoC 和依赖注入的示例。
http://www.tekpub.com/view/concepts/1
希望这会有所帮助!
【讨论】: