简单C#中的DI和IOC示例

时间:2012-02-09 21:23:55

标签: c# design-patterns

  

可能重复:
  Inversion of Control < Dependency Injection

请问有谁可以帮我理解DI和IOC的简单C#示例吗?据我所知,IOC是控制流的反转(这对我来说没什么意义),DI意味着通过属性或构造函数注入接口。不确定这两者是如何相关的。

谢谢。

4 个答案:

答案 0 :(得分:6)

假设您有一个需要服务的课程:

public class A 
{
  IEmailSender _emailSender
  public A(IEmailSender emailSender)
  {
    _emailSender = emailSender;
  }

  private void SendEmail()
  { 
    _emailSender.Send();
  }
}

A 现在被认为依赖于IEMailSender,这意味着它需要一个实现IEMailSender的对象才能执行它的功能。

像ninject或autofac这样的依赖注入框架将负责创建一个实现IEMailSender并将其注入 A 的构造函数的对象,只要你告诉他们如何创建这样的对象。

Ex使用ninject:

Bind<IEmailSender>().To<EmailSender>();

这告诉ninject,每当一个类需要一个IEMailSender时,给他们EmailSender(假设当然是EmailSender实现了IEMailSender接口)

这很简单,我希望这会有所帮助。

答案 1 :(得分:5)

我强烈建议您阅读Dependency Injection in .NET本书,详细介绍了所有方面的全面代码示例。对于控制的倒置,你应该参考Robert Martin的另一本书:Agile Principles, Patterns, and Practices in C#。它详细描述了SOLID原理以及示例和可理解的解释。这两本书真的帮助我理解了这些原则。

答案 2 :(得分:4)

我会添加一个解释,我被告知是一个有用的解释。

正如您正确指出的那样,依赖注入是一个类通过构造函数或setter注入来要求其协作者的行为。您可以将其视为一种编码技术。另一方面,控制反转更像是一种设计技术 - 一种哲学,如果你愿意的话。

在过程式编程(以及OO语言中的过程式编程)中,您通常会有某种“命令和控制”哲学。如果您正在创建一个由三个楼层对象组成的房屋对象,每个楼层对象由一些房间对象组成,则您创建一个房屋对象,其构造函数实例化三个楼层对象,每个楼层对象的构造函数依次实例化房间对象。

当您反转控制时,您正在反转命令和控制范例。有了IoC,当我去实例化一个房子时,它并没有为我提供所有细节。相反,它通过它的构造函数(和依赖注入)说,“你不能在没有一些楼层的情况下实例化我”。所以,你去实例化地板,他们说“不,不是没有一些房间”。现在,在这种“倒置”的风格中,我们的房子并没有控制房间的创造 - 它把它留给别人,而是表达了它只会对它所给予的房间做什么。这是可取的,因为通过在其头部翻转命令和控制,您可以获得更好的接缝来推理和测试代码 - 将事物解构为组件更容易。

因此,总而言之,控制的倒置是哲学,依赖注入是实现它的手段。

答案 3 :(得分:2)

DI是IoC。控制反转意味着交换谁决定如何实现任务。

在旧的世界中,您可以创建一个名为Logger的类,并在该类中创建一个名为LogTime()的方法。它的唯一目的是将当前时间写入文件。

public void LogTime()
{
    WriteToFile(GetCurrentTime());
}

这里的类有一个名为WriteToFile和GetCurrentTime的方法。 IoC只是意味着,而不是Logger类决定如何写入文件,甚至获取当前时间,您可以让外部提供者提供这些详细信息。

这就是DI的用武之地。你注入一个依赖。该方法取决于写入文件和获取当前时间的方法。你注入了那些方法。

DI有两种常见的模式,即属性注入和构造函数注入。他们按照他们对锡的说法行事。如何进行注入的特定框架。

有些使用属性,有些使用配置文件。有些采取最好的猜测方法。

沿着DI,你有SL(服务地点)就像礼貌的DI。在DI你说“采取这种依赖并喜欢它”。使用SL,上面的Logger类会说“是否有可能有一些东西来填补这种依赖性?”。看到?礼貌。

使其工作的核心是接口。 LogToFile可能是ILogsToFiles接口上的方法。然后,您可以拥有该界面的六种不同实现,并注入最合适的。

有许多框架可供您管理所有这些,但一个简单的ServiceLocator是10行代码,一个简单的DI可能不超过两倍。你很快就会开始想要额外的。看看Ninject吧。我推荐它纯粹是因为它小而简单,可能是一个很好的起点。