【问题标题】:Examples of IoC Containers [closed]IoC 容器的示例 [关闭]
【发布时间】:2009-04-20 20:51:42
【问题描述】:

有没有人有 IoC 容器的好例子(最好是在 c# 中)以及如何以及为什么使用它们?我已经查看了wiki pageAyende's 示例,但我还不太了解这个概念。

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

【问题讨论】:

    标签: c# inversion-of-control


    【解决方案1】:

    我已经使用了很多 StructureMap。你的问题的其余部分已经加载完毕。我将尝试用一个例子来解释这个概念。

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

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

    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>();
    

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

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

    所有这些映射都与您的实现代码分开,您可以在稍后将它们替换掉,几乎不需要重构。 IoC 容器还有很多内容,但这是基本概念。您也可以自动注入构造函数以避免直接调用ObjectFactory

    希望这会有所帮助!

    【讨论】:

    • 谢谢你的好例子:)。我知道问题的最后一部分有点宽泛,但我想你也回答了那部分。
    • 我可以建议更正吗? PaymentProcessor获取实例的代码不应该是这样的吗? PaymentProcessor processor = ObjectFactory.GetInstance&lt;IPaymentProcessor&gt;();
    【解决方案2】:

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

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

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

    【讨论】:

    • 您使用的是哪个容器?这一定很糟糕——今天没有广泛使用的容器有这些限制(除了“忘记注册”问题。)
    • 还没有看到有这些缺点的容器——即使是“忘记注册”也不是一个真正的有效点,因为等效项(没有 IoC)在构造函数中注入 null,但在运行时仍然失败.
    【解决方案3】:

    如果您想了解 IoC 容器的底层内容,以及重点(依赖注入),DNR TV (Episode 126) 上有一个很棒的播客,其中详细介绍了如何创建它们,为什么需要他们。这是一个非常棒的播客。观看此视频后,您将能够查看 UnityNinjectStructureMap 等并了解他们在做什么

    【讨论】:

    • James Kovacs 视频的链接已失效,但可以在 here 找到。 IoC 部分于 27:27 开始。
    • 与 Unity 的链接也是如此,因为今年 codeplex 将离线。 (新链接:github.com/unitycontainer/unity
    【解决方案4】:

    查看 Spring IoC (.net) 一个 java/.net 容器。文档介绍的挺不错的。

    简而言之: 您可以将 IoC 视为一种鼓励: 对象组合接口编程

    这将为您提供以下信息:

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

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

    • 扩展或修改字节编译应用程序的能力(Java 是这样,我不确定 .net 是不是这样)。

    【讨论】:

    • 感谢您的阅读!
    【解决方案5】:

    我们使用 Ninject 是因为它简单的 API 和快速的对象解析。它有很好的文档记录,并利用 lambda 表达式等 C# 3.0 特性来简化规范。

    您可以在 Ninject here 上找到几个截屏视频

    【讨论】:

      【解决方案6】:

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

      【讨论】:

      • 不,我还没有尝试构建一个,这是我试图更好地理解的概念。
      【解决方案7】:

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

      您可能想看一下this answer,我在其中讨论了 IoC 容器的基本用法(我一直认为通过一个简单的示例更容易理解)——这可能有助于您进一步理解.基本上,IoC 容器可以帮助您构建满足所有依赖项的对象,并允许您以最少的配置代码更改您的依赖项。

      【讨论】:

        【解决方案8】:

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

        【讨论】:

          【解决方案9】:

          我将 Unity 用于我的 IoC 容器,但容器之间的区别不仅仅在于您可以使用 DI 做什么。

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

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

          例如,如果您使用 Spring.NET,您将可以访问一个非常强大的框架,但它可能会做很多您不会使用的工作,因此请寻找更小的框架。我认为最好的规则是找到满足您需求的最小、最简单的实现,然后使用它。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-11-26
            • 1970-01-01
            • 2014-06-22
            • 1970-01-01
            • 1970-01-01
            • 2013-08-26
            • 2011-12-07
            • 2011-04-29
            相关资源
            最近更新 更多