Ale*_*pka 2 c# singleton ioc-container
我公司的MVC解决方案使用IOC容器将Caching/Repository层注入控制器.这是非常昂贵的,因为目前我们每次创建控制器时都会生成新类(当缓存层对象已经引用了repo层时,可以达到数千个对象 - 并且所有这些类都被创建).我知道Singleton模式由于很多原因而非常不喜欢(参见为什么Singletons是邪恶的)但是有没有理由不将IOC Container设置为缓存/ repo层对象的单例?
谢谢.
你搞混了.Singleton设计模式与DI库使用的Singleton生活方式完全不同.
使用Singleton模式,您通常在具体类上定义一个公共只读字段,该类包含该类的唯一实例; 此实例由类本身创建,整个应用程序可以访问该只读字段.
使用Singleton生活方式,您可以指示容器在该容器的生命周期内只创建一个实例并重复使用它.
Singleton设计模式是一个问题,因为它迫使消费者对具体类(依赖性反转原则违规)采取硬依赖,并且由于该具体类在内部控制创建,因此在使用期间使用虚假实现变得更加困难.测试.除此之外,由于消费者没有需要该类作为依赖关系的构造函数,因此有效地使读取代码的人隐藏依赖关系,创建测试,并从工具中作为可以为您进行对象图分析的DI库.实际上你指出的这篇文章在解释为什么Singleton设计模式不好时确实做得非常好.
然而,文章从未真正提到过Singleton的生活方式,但由于它讨论了Singleton设计模式如何隐藏依赖关系,因此它意味着应该注入依赖关系.并且由于您希望某些类具有一个实例并通过构造函数注入它们,因此Singleton生活方式是此问题的实际解决方案.
Singleton生活方式解决了这些问题,因为您从具体类中移除了创建该单个实例的责任,这允许消费者在其构造函数中依赖于抽象,这使得依赖性可见并且代码更易于测试.
因此,使您的注册单身人士没有任何问题.事实上,我认为你应该选择尽可能多的注册单例,因为这可以防止开发人员在实现依赖注入时通常面临的大量问题.通过使每个组件不可变和无状态,它们变得更容易推理并且您防止自己意外地将运行时数据注入到组件中,这是不好的做法.DI的另一个常见缺陷是Captive Dependencies,这意味着组件依赖于另一个应该具有较短生活方式的组件.如果你使所有组件都是不可变的,无状态的和单独的,那么Captive Dependencies的问题就会消失,因为单例组件可以安全地相互依赖.
当然,您总是需要组件中的运行时数据(例如请求数据,O/RM上下文等),但这些可以在运行时通过将提供程序或简单Func<DbContext>注入适配器实现来请求,这些实现可以抽象第三方工具.您的申请(如果您遵循SOLID,这是一个很好的做法).此Stackoverflow 答案详细介绍了这一点.
| 归档时间: |
|
| 查看次数: |
1560 次 |
| 最近记录: |