IoC容器的示例

Mor*_*rph 44 c# inversion-of-control

有没有人有很好的IoC容器示例(最好是在c#中)以及使用它们的方式和原因?我查看了维基页面艾恩德的例子,但我还没有完全理解这个概念.

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

Jab*_*Jab 57

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

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

相反,您将创建和编码这样的接口:

interface IPaymentProcessor
{
    bool ProcessPayment(amount, ....);
}
Run Code Online (Sandbox Code Playgroud)

例如,您的所有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, ...);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是IoC容器的用武之地.您可以让IoC容器注入依赖项,而不是手动调用构造函数.

PaymentProcessor processor = ObjectFactory.GetInstance<PaymentProcessor>();
Run Code Online (Sandbox Code Playgroud)

这段代码告诉StructureMap"任何时候你看到一个需要的构造函数IPaymentProcessor,返回一个新的PayPalPaymentProcessor".

ObjectFactory.Initialize(x =>
{ 
    x.ForRequestedType<IPaymentProcessor>().TheDefaultIsConcreteType<PayPalPaymentProcessor>();
});
Run Code Online (Sandbox Code Playgroud)

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

希望这可以帮助!


小智 23

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

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

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

  • 你使用的是哪个容器?它一定非常糟糕 - 今天没有广泛使用的容器有这些限制(除了"忘记注册"问题.) (17认同)

Jos*_*eph 8

如果你想看到一个IoC容器,还有点(依赖注入),DNR TV(第126集)上有一个很棒的播客,它真正详细介绍了如何创建它们,为什么你需要它们.这是一个非常精彩的播客.一旦你看了这个视频,你就可以看看Unity,Ninject,StructureMap等,并且能够理解他们在做什么