IoC容器的示例

时间:2009-04-20 20:51:43

标签: c# inversion-of-control

有没有人有很好的IoC容器示例(最好是c#)以及使用它们的方式和原因?我已经查看了wiki pageAyende's示例,但我还没有完全了解这个概念。

我应该何时何地使用IoC容器?

9 个答案:

答案 0 :(得分:54)

我已经使用了StructureMap了很多。你问的其余部分非常重要。我将尝试在一个例子中解释这个概念。

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

相反,您可以针对这样的界面创建和编码:

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

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

现在您有一个实际用于处理付款的对象。这可以是一个Controller(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>();

这段代码告诉StructureMap“只要你看到需要IPaymentProcessor的构造函数,就返回一个新的PayPalPaymentProcessor”。

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

所有这些映射都与您的实现代码分开,您可以在以后更换这些映射,只需要很少的重构。 IoC容器还有很多,但这是基本概念。您可以自动注入构造函数,以避免直接调用ObjectFactory

希望这有帮助!

答案 1 :(得分:22)

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

  • 构造函数抛出的异常会被吞噬。您只能获得“无法创建依赖”异常。这意味着如果抛出构造函数,就无法捕获预期的异常。
  • 无法单步执行构造函数。
  • 忘记在运行时注册接口,而不是编译时间。
  • 您的所有类只能有一个构造函数,并且它们都必须接受接口作为参数。
  • 所有依赖项都已实例化,因此您无法共享实例,这意味着您的内存使用量会很快变大。
  • 它促进了许多相互依赖,这可以隐藏你的代码变成意大利面的事实。让所有这些相互依赖性更容易实现,只会掩盖存在潜在的潜在问题。
  • 您无法轻松管理自己的“工作单元”,因为您无法管理跨多个依赖项的事务,因为您无法控制实例化它们并传入该事务的上下文。

不要误会我的意思,我喜欢依赖注入和控制原理的反转,但我认为IOC容器可以负责任地使用,但是请注意由于上面的列表你需要战斗的战斗

答案 2 :(得分:8)

如果你想看到一个IoC容器,还有点(依赖注入),DNR TV(Episode 126)上有一个很棒的播客,它真正详细介绍了如何创建它们,为什么你需要它们。这是一个非常精彩的播客。观看完视频后,您就可以查看UnityNinjectStructureMap等,并了解他们正在做的事情

答案 3 :(得分:3)

查看Spring IoC (.net) java / .net容器。文档是非常好的介绍。

简要说明: 您可以将IoC视为一种鼓励: 对象组合编程到接口

这为您提供以下内容:

  • 轻松单元测试代码的能力(您可以通过模拟其所有依赖项轻松地单独测试对象)。

  • 非常先进的配置(因为你的IoC程序只是一堆对象和将对象粘合在一起的配置)。

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

答案 4 :(得分:2)

我们使用Ninject,因为它具有简单的API和快速的对象分辨率。它有很好的文档记录,并利用像lambda表达式这样的C#3.0特性来简化规范。

您可以在Ninject here

上找到几个截屏视频

答案 5 :(得分:1)

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

您可能想看看this answer我在哪里谈论IoC容器的基本用法(我总是认为通过一个简单的例子可以更容易理解) - 这可能有助于您理解事物再多一点。基本上,IoC容器可以帮助您构建满足所有依赖关系的对象,并允许您使用最少的配置代码更改依赖关系。

答案 6 :(得分:1)

尝试阅读Introduction to Unity Application Block,在ASP.NET StoreFront: Dependency Injection截屏视频中,您可以看到有关依赖注入概念的更多信息。

答案 7 :(得分:0)

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

答案 8 :(得分:0)

我正在使用Unity作为我的IoC容器,但容器之间的差异远远超过了你可以用DI做的事情。

DI(依赖注入)主要是一种在程序的不同部分之间获得更松散耦合的方法。所以,如果你写了一个你喜欢它的工作方式的游戏,通过使用DI,你可以改变游戏中的角色或物理引擎,而无需改变游戏的其他部分,所以,如果有人付出更多的钱,他们会得到更真实的引擎,或者更好的角色,但由于没有其他任何变化,测试更简单。

使用DI可以更轻松地进行单元测试,因为您可以模拟数据库,例如,只需更改应用程序将使用的实现,而不会影响其他任何内容。

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