35

我一直在研究城堡项目,特别是温莎。我对这项技术的可能性印象深刻,拥有如此松散耦合的系统的好处是显而易见的。我唯一不确定的是使用这种方法是否有任何缺点,特别是在 asp.net 中?例如性能命中等。

我正试图让我的开发人员在这里看到这种方法的好处,并受到以下复出的打击:

  1. 那是使用反射,每次从容器调用对象时,都必须使用反射,因此性能会很糟糕。(是这样吗?它是否在每次调用时都使用反射?)

  2. 如果我依赖接口;如何处理具有附加到类上的额外方法和属性的对象?(通过继承)

4

7 回答 7

34

要回答您的问题:

  1. 那是使用反射,每次从容器调用对象时,都必须使用反射,因此性能会很糟糕。(是这样吗?它是否在每次调用时都使用反射?)
  • 不,不是的。大多数情况下,当您注册组件时,它很少使用反射。当你第一次从容器请求组件时,它也可能在生成代理类型时使用反射。
  1. 如果我依赖接口;如何处理具有附加到类上的额外方法和属性的对象?(通过继承)
  • 这都是设计问题。您不想让容器创建每个对象。您主要将其用于服务依赖项。在这种情况下,您并不关心实际上隐藏在接口后面的是什么类型(这就是它的全部意义,不是吗?)。

您也可以拥有类组件,但它们有限制,您必须了解这些限制(例如,您不能拦截对非虚拟方法的调用)。我发现 Windsor 是最成熟的,最适合我的开发容器风格。

除此之外,Performance,我还没有听说过因为不可接受的性能而不得不丢弃依赖容器的项目。Windsor 真的很聪明,它缓存了冗长操作的结果,这样你就不必付出两次代价。您可以在 Internet 上找到图表,比较许多 IoC 容器的速度。关于这些需要注意两点:所有容器都非常快。不要认为其他容器在这些图表上比 Windsor 更快的事实意味着它们更好。Windsor 为您做了很多其他容器没有的事情。

于 2008-12-29T10:33:38.430 回答
21

我在几个高负载下的生产应用程序中使用了 IoC 容器(Spring.NET 和 StructureMap)(不是 Facebook/MySpace 高,但足以对一些服务器造成压力)。

根据我的经验,甚至在我开始使用 IoC 之前,最大的性能问题就是数据库以及与数据库的交互——优化查询、索引、使用二级缓存等。

如果您的应用程序涉及数据库,那么与数据库往返相比,Windsor 或任何其他容器可能导致的任何性能损失都将非常小。

这就像人们在 1-10 毫秒内比较 new() 运算符与 Activator.CreateInstance() 的性能影响,而单个数据库往返通常要贵一个数量级。

我建议你不要担心小事,而专注于大事。

另外,我想建议你看看 StructureMap,因为我相信它比 Windsor 有更多的功能,并且没有 Windsor 的很多缺点(即坚持引用并要求你发布它们等) .

于 2008-12-23T15:45:35.217 回答
10

我遇到的 Castle Windsor 的一个问题是它无法在 Medium Trust 中运行(没有我无法进行的重新编译)。所以我需要从 Windsor 切换到 Unity。

根据 DI/IoC 性能 - 我相信性能影响并不大,尤其是当您牢记它的强大功能时。

顺便说一句:如果您从 DI/IoC 开始,您应该阅读这篇 MSDN 文章

于 2008-12-23T08:38:08.150 回答
7

巨大的启动成本,在运行期间几乎没有性能损失(当然,没有对调用的反射——一切都是在实例化期间编译的)。温莎有点偏重,但是通过适当的生命周期管理应该不会造成任何问题。

一个更重要的缺点是在构建过程中没有发现集成问题,有些甚至在发布时都没有。如果没有仔细跟踪所有模块的版本和对整个系统的持续测试,很容易陷入困境。反射在这里有所帮助,因此 Windsor 在这方面比许多其他 DI 框架更好。

于 2008-12-23T09:40:17.497 回答
4

在我的经验中,IoC 容器的性能不可接受的一个例外是在尝试将 IoC 容器集成/包装为 IServiceProvider 以在 ComponentModel 中使用时——一个曾经常见的例子是在创建自己的托管 winforms 设计器时(通常构建某种自定义设计器,即工作流/流程图等)

由于许多 winforms 组件的行为方式,尤其是在设计时,解析组件的成本将物理上导致鼠标在拖动时“卡顿”,因为该框架每秒可以进行 30,000 次以上的服务解析调用 - 这更多尽管我认为是对组件本身的不良编码实践的反思,或者至少是由于对服务提供商实现快速/简单的假设。

在实践中,我从来没有发现即使在负载很重的商业应用程序中组件解析时间也是一个问题。

于 2009-01-05T19:03:59.523 回答
2

关于性能,请参阅以下文章:

但请记住,其中一些容器具有更新(可能更快)的版本——尤其是 Unity。

于 2008-12-23T10:00:21.323 回答
0
  1. 那是使用反射,每次从容器调用对象时,都必须使用反射,因此性能会很糟糕。(是这样吗?它是否在每次调用时都使用反射?)

据了解,所有好的容器(这里包括温莎城堡)都使用反射来创建新实例。但是,这是提高性能。这是为了与慢得多的 Activator.CreateInstance 进行比较。其他一些容器虽然速度很快,但可以与新的运营商竞争。在此处查看比较基准。温莎城堡不是高性能的,但是速度并不是很重要。在应用程序中使用 IoC 时。90% 的类应该设置为单例,这意味着只在应用程序启动时工作。

  1. 如果我依赖接口;如何处理具有附加到类上的额外方法和属性的对象?(通过继承)

试试这个教程这个教程。它将揭示您问题的答案。如果您想避免设计问题和易于维护的软件,我强烈建议您进行SOLID 实践

于 2015-07-30T15:39:42.063 回答