依赖注入作用域为瞬态,然后瞬态为单例
Posted
技术标签:
【中文标题】依赖注入作用域为瞬态,然后瞬态为单例【英文标题】:Dependency injection Scoped into Transient and then Transient into Singleton 【发布时间】:2021-01-14 20:04:06 【问题描述】:我有一个 scoped
Context
正在通过方法从 transient
服务访问。
这个transient
服务被注入到singleton
服务中。
我的 scoped
Context
会变成单例还是保持范围?
public class Context : IContext
public string CorrelationId get; set;
public Context(string id)
CorrelationId = id;
上下文访问器:
internal class RequestContextRegistrator : IRequestContextRegistrator
private IContext context;
public IContext RegisterContext(IContext context)
this.context = context;
return context;
public IContext Get()
return context ?? new Context()
CorrelationId = context.CorrelationId
;
单例对象:
public class QueueSender<TCommand>
private readonly IRequestContextRegistrator provider;
public QueueSender(IRequestContextRegistrator provider)
this.provider = provider;
public async Task Send(TCommand command)
var context = provider.Get();
var message = PrepareServiceBusMessage(command, userAgent, context?.CorrelationId);
整个想法是能够传递特定“请求”独有的上下文 ID。请求不是来自dotnet
控制器,它来自队列接收器类。
或者解释一下,这种到单例的转换对于依赖注入树的深度有多大。
【问题讨论】:
【参考方案1】:我的作用域上下文会变成单例还是保持作用域?
它将保持范围。
您的单例实例将注入一个RequestContextRegistrator
,而这又将注入一个Context
;这个 Context
实例将一直存在,直到您的应用程序终止,因为单例将保留其引用,但是,任何其他需要 IContext
的类都将注入一个 new Context
。
【讨论】:
那最终不会导致内存泄漏吗? 只有在卸载包含AppDomain
时,才会对单例及其依赖项进行垃圾回收;因为您正在创建一个单例,所以您明确要求这种行为。仅涉及 3 个实例,因此不会导致内存问题。
每个队列消息都会有一个新的context
,如果服务消耗了 1.000.000 条消息不是问题吗?
什么是队列消息?您尚未共享任何其他将 IContext
作为依赖项的类。
QueueSender
发送队列消息。【参考方案2】:
不要从单例解析范围服务。可能会导致服务在处理后续请求时状态不正确。没关系:
从范围服务或临时服务中解析单例服务。 从另一个范围服务或临时服务中解析一个范围服务。请查看此链接Service lifetime
【讨论】:
以上是关于依赖注入作用域为瞬态,然后瞬态为单例的主要内容,如果未能解决你的问题,请参考以下文章