IoC容器的例子

有没有人有很好的IoC容器的例子(最好在C#中)以及如何以及为什么使用它们? 我已经检查了wiki页面和Ayende的例子,但我还没有完全理解这个概念。

何时何地使用IoC容器?

我用了很多结构图 。 你的问题的其余部分是相当的加载。 我会试着在一个例子中解释这个概念。

假设您创build了一个可以通过PayPal接受付款的网站。 贝宝现在是一个依赖。 但是您不想针对特定的PayPal提供商进行编码。

相反,你会创build和编码这样的界面

interface IPaymentProcessor { bool ProcessPayment(amount, ....); } 

所有的PayPal代码将驻留在实现接口方法的类中。 PayPalPaymentProcessor为例

现在你有一个实际用来处理付款的对象。 这可能是一个控制器(asp.net-mvc,ViewModel-wpf)或只是一个类,如下所示。

 class PaymentProcessor { private IPaymentProcessor _processor = null; public PaymentProcessor(IPaymentProcessor processor) { _processor = processor; } public bool ProcessTransaction(Transaction trans) { _processor.ProcessPayment(trans.amount, ...); } } 

这是一个IoC来的地方。你不用手动调用构造函数,而是让IoC 注入依赖项。

 PaymentProcessor processor = ObjectFactory.GetInstance<PaymentProcessor>(); 

这段代码告诉结构图“任何时候你看到一个需要IPaymentProcessor的构造函数,返回一个新的PayPalPaymentProcessor”。

 ObjectFactory.Initialize(x => { x.ForRequestedType<IPaymentProcessor>().TheDefaultIsConcreteType<PayPalPaymentProcessor>(); }); 

所有这些映射都与您的实现代码是分开的,您可以在稍后重新进行这些映射,而不需要重构。 IoCs还有很多,但这是一个基本的概念。 您可以自动注入构造函数以避免直接调用ObjectFactory。

希望这可以帮助!

请注意IOC容器的以下限制。 我必须警告人们,因为我忍受着不得不支持使用它的系统的地狱:

  • 被构造函数抛出的exception被吞下。 你只会得到“无法创build依赖”的例外。 这意味着如果抛出构造函数,就不能捕获预期的exception。
  • 不能通过构造函数。
  • 忘记在运行时注册一个接口,而不是编译时。
  • 所有的类只能有一个构造函数,并且都必须接受接口作为参数。
  • 所有依赖关系都被实例化,所以你不能共享实例,这意味着你的内存使用量可能会很快变大。
  • 它促进了很多相互依赖,可以隐藏你的代码已经变成意大利面的事实。 让所有这些相互依存更容易安置,只是掩盖了潜在的潜在问题。
  • 你不能很容易地pipe理你自己的“工作单元”,因为你不能pipe理一个跨越多个依赖的事务,因为你没有控制实例化它们并在那个事务的上下文中传递。

不要误解我的意思,我喜欢dependency injection和控制原理的倒置,但是我认为国际奥委会的容器可以负责任的使用,但是要注意上面的清单需要打的战斗。

如果你想看到一个IoC容器,还有一点(dependency injection),那么在DNR电视( 第126集 )上有一个非常棒的播客,它详细介绍了如何创build它们,为什么你需要它们。 这是一个非常棒的播客。 看完这个video之后,你就可以看到Unity , Ninject , StructureMap等,并且能够理解他们在做什么

查看Spring IoC(.net) java / .net容器。 这个文档是相当不错的介绍。

简而言之:您可以将IoC视为一种架构,鼓励: 对象组合编程到界面

这给你以下几点:

  • 可以轻松地对代码进行unit testing(您可以通过模拟所有的依赖关系来轻松testing您的对象)。

  • 一个非常先进的configuration(因为你的IoC程序只是一堆对象和一个把对象粘在一起的configuration)。

  • 能够扩展或修改字节编译的应用程序(这对于Java来说是真实的,我不确定它是否适用于.net)。

我们使用Ninject是因为它具有简单的API和快速的对象分辨率。 它有很好的文档logging,并利用了像lambdaexpression式这样的C#3.0特性来使得规范更容易。

您可以在这里findNinject上的几个截屏video

我通常使用StructureMap – 主要是因为我熟悉语法。 我也听说过关于autofac的好消息 ,我期待在碰到v2时试用Ninject 。

你可能想看看这个答案 ,我在这里谈论一个IoC容器的基本用法(我总是认为用一个简单的例子就可以更容易理解) – 这可能会帮助你更多地理解事情。 基本上,IoC容器可以帮助您构build满足所有依赖关系的对象,并允许您使用最less的configuration代码来更改依赖关系。

您是否正在尝试构build一个IoC容器,为什么不使用Spring.NET,StructureMap或Unity Application Block等可用的容器? 以下是开源IoC项目列表

尝试阅读介绍Unity应用程序块和ASP.NET StoreFront:dependency injection截屏,您可以看到更多关于dependency injection概念。

我为我的IoC容器使用Unity,但容器之间的区别在于您可以使用DI执行的操作。

DI(dependency injection)主要是一种在程序的不同部分之间获得更多松散耦合的方式。 所以,如果你写了一个你喜欢它的游戏,那么通过使用DI,你可以改变游戏中的angular色或物理引擎而不改变游戏的其他部分,所以如果有人支付更多的钱,他们会得到更逼真的引擎,或更好的字符,但由于没有其他变化,testing更简单。

使用DI进行unit testing也比较容易,因为您可以嘲笑数据库,例如只需更改应用程序将使用的实现,而不会影响其他任何内容。

例如,如果你使用Spring.NET,你可以访问一个非常强大的框架,但它可能会做很多事情,你不会使用,所以寻找更小的东西。 我认为最好的规则是find满足您的需求的最小,最简单的实现,并使用它。