我正在使用依赖注入:我应该将哪些类型绑定为单例? [英] I'm using Dependency Injection: which types should I bind as singletons?

查看:83
本文介绍了我正在使用依赖注入:我应该将哪些类型绑定为单例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于单身人士是否不好"以及使用什么模式代替,存在很多问题.他们通常专注于单例设计模式,这涉及从类上的静态方法检索单例实例.这不是这些问题之一.

There are a lot of questions out there about whether singletons are "bad," and what patterns to use instead. They're generally focused on the singleton design pattern, which involves retrieving the singleton instance from a static method on the class. This is not one of those questions.

自从几个月前我真正发现"依赖注入以来,我一直在推动它在我们团队中的采用,随着时间的推移从我们的代码中删除静态和单例模式,并尽可能使用基于构造函数的注入.我们采用了约定,因此我们不必继续为DI模块添加显式绑定.我们甚至使用DI框架来提供记录器实例,以便我们可以自动告诉每个记录器其所属的类,而无需其他代码.现在,我有了一个地方可以控制各种类型的绑定方式,因此很容易确定特定类别的类(实用程序类,存储库等)的生命周期.

Ever since I really "discovered" dependency injection several months back, I've been driving its adoption in our team, removing static and singleton patterns from our code over time, and using constructor-based injection wherever possible. We've adopted conventions so that we don't have to keep adding explicit bindings to our DI modules. We even use the DI framework to provide logger instances, so that we can automatically tell each logger which class it's in without additional code. Now that I have a single place where I can control how various types are bound, it's really easy to determine what the life cycle of a particular category of classes (utility classes, repositories, etc.) should be.

我最初的想法是,如果我期望将类作为单例绑定,则可能会有一些优势.这只是意味着要进行的 new 操作要少得多,尤其是当您创建的对象最终具有较大的依赖关系树时.这些类中的几乎所有非静态字段都是将这​​些值注入到构造函数中,因此在不使用实例时保留实例的内存开销相对较小.

My initial thinking was that there would probably be some advantage to binding classes as singletons if I expected them to be used fairly often. It just means there's a lot less newing going on, especially when the object you're creating ends up having a big dependency tree. Pretty much the only non-static fields on any of these classes are those values getting injected into the constructor, so there's relatively little memory overhead to keeping an instance around when it's not being used.

然后我在www.codingwithoutcomments.com上读到"Singleton我爱你,但你让我失望",这让我怀疑我是否有正确的主意.毕竟,默认情况下,Ninject会编译对象创建函数,因此创建这些对象的其他实例所涉及的反射开销很少.因为我们将业务逻辑排除在构造函数之外,所以创建新实例确实是一种轻量级的操作.而且这些对象没有一堆非静态字段,因此创建新实例也不会涉及很多内存开销.

Then I read "Singleton I love you, but you're bringing me down" on www.codingwithoutcomments.com, and it made me wonder whether I had the right idea. After all, Ninject compiles object-creation functions by default, so there's very little reflection overhead involved in creating additional instances of these objects. Because we're keeping business logic out of the constructor, creating new instances is a really lightweight operation. And the objects don't have a bunch of non-static fields, so there isn't a lot of memory overhead involved in creating new instances, either.

因此,在这一点上,我开始认为这两种方式都可能无关紧要.我还没有考虑其他因素吗?通过更改某些类型的对象的生命周期,实际上没有人体验过性能的显着改善吗?遵循DI模式是唯一真正重要的事情,还是有其他原因使使用对象的单个实例本质上是不好的"?

So at this point, I'm beginning to think that it probably won't matter much either way. Are there additional considerations I haven't taken into account? Has anyone actually experienced a significant improvement in performance by changing the life cycles of certain types of objects? Is following the DI pattern the only real important thing, or are there other reasons that using a single instance of an object can be inherently "bad?"

推荐答案

我正在使用单例实例来缓存昂贵的对象(例如nhibernate会话工厂)或要在应用程序中共享的对象.

I am using singleton instances to cache expensive to create objects (like nhibernate session factory) or for objects I want to share across the application.

如果不确定,我希望每次使用该对象时都重新创建该对象,并仅在确实需要时将其标记为单例或按线程"/按请求"/随便什么".

If in uncertainty I would rather have the object be recreated every time it is used and mark it as singleton or "per thread"/"per request"/"per whatever" only if you really need to.

在各处散布单例以潜在地节省一些更新是过早的优化,并且可能导致真正的讨厌的错误,因为您不确定对象是新的还是在多个对象/实例之间共享.

Scattering singletons all over the place to potentially save some newing up is premature optimization and can lead to really nasty bugs because you can't be sure if the object is new or shared across multiple objects/instances.

即使对象目前没有任何状态并且似乎可以共享,某人也可以稍后重构并为其添加状态,然后状态可能会在不同的对象/实例之间无意共享.

Even if the object has no state at the moment and seems save to share, someone can refactor later and add state to it which then may be unintentionally shared between different objects/instances.

这篇关于我正在使用依赖注入:我应该将哪些类型绑定为单例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆