使用IoC,可以向Singleton注入具有瞬态寿命的对象吗?

时间:2023-02-06 04:02:19

We have an ASP.NET MVC app using IoC to inject Service references into controllers and Repository references into Services.

我们有一个ASP.NET MVC应用程序,使用IoC将服务引用注入控制器,将存储库引用注入服务。

Controllers have to have a Lifetime of Transient as they must be instantiated per request. If the whole IoC stack is being newed-up per request, though, this gets to be a bit of overhead. We have more dependencies than I'd like, and one option would be to have more controllers, each with fewer dependencies in the stack. But, leaving that aside for now, my question is, if an object that is injected as a singleton has dependencies that have a transient lifetime, will those dependencies essentially be treated like singletons by virtue of being owned by the Singleton?

控制器必须具有瞬态寿命,因为它们必须根据请求进行实例化。但是,如果整个IoC堆栈按请求进行新增,则会产生一些开销。我们有比我想要的更多的依赖,一个选项是拥有更多的控制器,每个控制器在堆栈中具有更少的依赖性。但是,暂时把它放在一边,我的问题是,如果一个注入单身的对象具有一个具有瞬态生命的依赖,那么这些依赖性是否会因为被Singleton拥有而被视为单身?

Specifically, if we have the following

具体来说,如果我们有以下内容

RepositoryA (needs to be transient because current design injects a user context in constructor) ServiceA (singleton) ControllerA (transient)

RepositoryA(需要是瞬态的,因为当前设计在构造函数中注入用户上下文)ServiceA(单例)ControllerA(瞬态)

instantiated like so:

实例化如下:

public ServiceA(IRepositoryA repo) {}
public ControllerA(IServiceA service) {}

Will RepositoryA essentially be instantiated once because ServiceA is instantiated once?

RepositoryA实际上是否会被实例化一次因为ServiceA被实例化一次?

I'm 99% sure the answer is yes, but just wanted to confirm the amount of refactoring I have to do here.

我99%肯定答案是肯定的,但只想确认我必须在这里做的重构数量。

Also, assuming Services and Repositories did NOT have any user/request-specific instance variables, as a design approach, is there any reason not to use a Singleton lifetime for them?

此外,假设服务和存储库没有任何特定于用户/请求的实例变量,作为一种设计方法,是否有任何理由不对它们使用Singleton生命周期?

1 个解决方案

#1


4  

if an object that is injected as a singleton has dependencies that have a transient lifetime, will those dependencies essentially be treated like singletons by virtue of being owned by the Singleton?

如果作为单例注入的对象具有具有瞬态生命周期的依赖关系,那么这些依赖关系是否会因为被Singleton拥有而被视为单例?

That's correct. Since such component holds on to its dependencies (by storing their reference in a private field), those dependencies will live as long as the component itself does. In other word, their lifetime is implicitly promoted to the lifetime of the component (if their lifetime is shorter).

那是对的。由于此类组件保留其依赖项(通过将其引用存储在私有字段中),因此只要组件本身存在,这些依赖项就会存在。换句话说,它们的生命周期被隐含地提升到组件的生命周期(如果它们的生命周期更短)。

If you have this, your DI configuration is most certainly wrong and sooner or later this bug will show up. Probably only in production and hardly ever on your dev machine :-S.

如果你有这个,你的DI配置肯定是错误的,迟早会出现这个错误。可能只在生产中,几乎没有在您的开发机器上:-S。

In general all components managed by the container should only depend on abstractions that have a lifespan that is equal or longer than that of the component itself.

通常,容器管理的所有组件应仅依赖于寿命等于或长于组件本身的抽象。

Some frameworks even have analysis services in place to detect these kinds of configuration errors. Nonetheless, you should be very careful when wiring up all dependencies. In general it would be safest to configure components as transient whenever possible, since a transient components is allowed to contain dependencies of any lifestyle. Having many transient objects would normally not be a performance problem. Building a rather large object graph per web request would typically be fast enough (otherwise try switching to a DI framework with a higher throughput).

一些框架甚至具有分析服务来检测这些类型的配置错误。尽管如此,在连接所有依赖项时应该非常小心。通常,尽可能将组件配置为瞬态是最安全的,因为允许瞬态组件包含任何生活方式的依赖性。拥有许多瞬态对象通常不会成为性能问题。每个Web请求构建一个相当大的对象图通常足够快(否则尝试切换到具有更高吞吐量的DI框架)。

#1


4  

if an object that is injected as a singleton has dependencies that have a transient lifetime, will those dependencies essentially be treated like singletons by virtue of being owned by the Singleton?

如果作为单例注入的对象具有具有瞬态生命周期的依赖关系,那么这些依赖关系是否会因为被Singleton拥有而被视为单例?

That's correct. Since such component holds on to its dependencies (by storing their reference in a private field), those dependencies will live as long as the component itself does. In other word, their lifetime is implicitly promoted to the lifetime of the component (if their lifetime is shorter).

那是对的。由于此类组件保留其依赖项(通过将其引用存储在私有字段中),因此只要组件本身存在,这些依赖项就会存在。换句话说,它们的生命周期被隐含地提升到组件的生命周期(如果它们的生命周期更短)。

If you have this, your DI configuration is most certainly wrong and sooner or later this bug will show up. Probably only in production and hardly ever on your dev machine :-S.

如果你有这个,你的DI配置肯定是错误的,迟早会出现这个错误。可能只在生产中,几乎没有在您的开发机器上:-S。

In general all components managed by the container should only depend on abstractions that have a lifespan that is equal or longer than that of the component itself.

通常,容器管理的所有组件应仅依赖于寿命等于或长于组件本身的抽象。

Some frameworks even have analysis services in place to detect these kinds of configuration errors. Nonetheless, you should be very careful when wiring up all dependencies. In general it would be safest to configure components as transient whenever possible, since a transient components is allowed to contain dependencies of any lifestyle. Having many transient objects would normally not be a performance problem. Building a rather large object graph per web request would typically be fast enough (otherwise try switching to a DI framework with a higher throughput).

一些框架甚至具有分析服务来检测这些类型的配置错误。尽管如此,在连接所有依赖项时应该非常小心。通常,尽可能将组件配置为瞬态是最安全的,因为允许瞬态组件包含任何生活方式的依赖性。拥有许多瞬态对象通常不会成为性能问题。每个Web请求构建一个相当大的对象图通常足够快(否则尝试切换到具有更高吞吐量的DI框架)。