【发布时间】:2021-09-05 04:23:18
【问题描述】:
我有 3 个接口(用于单例/作用域/瞬态):
public interface ISingleton
{
}
class Singlet : ISingleton
{
}
public interface IScoped
{
}
class Scoped : IScoped
{
}
public interface Itransient
{
}
class Transient : Itransient
{
}
我将它们注册为:
services.AddScoped<IScoped, Scoped>();
services.AddTransient<Itransient, Transient>();
services.AddSingleton<ISingleton, Singlet>();
如果我尝试向 singleton 注入作用域服务,我应该(并且确实)得到一个异常(我知道原因):
public interface ISingleton
{
}
class Singlet : ISingleton
{
public Singlet( IScoped sc)
{
}
}
某些服务无法构建(验证时出错 服务描述符 'ServiceType: WebApplication2.ISingleton 生命周期:单例实现类型:WebApplication2.Singlet': 无法从单例中使用范围服务“WebApplication2.IScoped” 'WebApplication2.ISingleton'。)
但是如果我尝试注入瞬态,我不会得到异常:
public interface ISingleton
{
}
class Singlet : ISingleton
{
public Singlet( Itransient tr)
{
}
}
问题:
为什么 .net 核心禁止注入引发异常的较短生命周期(范围)服务,而允许将瞬态注入单例?
【问题讨论】:
-
“为什么 .net 核心禁止注入较短生命周期(范围)的服务引发异常,同时允许将瞬态注入到单例中?” - 因为临时服务的生命周期无关紧要 - 它不是共享资源。
-
@Dai 但它仍然是临时服务的强制依赖。您所说的“无关紧要”是什么意思?那么为什么作用域很重要呢?
-
“它仍然是该瞬态服务的俘获依赖” - 您示例中的瞬态服务没有任何依赖关系。
-
@Dai 我正在重新考虑您所说的:这不是共享资源。....不是。
-
那么按照同样的逻辑,您是说不允许范围服务请求任何瞬态吗?单线体中的作用域注入的问题在于,相同的实例预计将用于该作用域内的所有内容,但在该作用域之外会创建一个新实例。该要求与单例冲突,因为单例已经创建,它将继续使用前一个范围中的范围实例。对于瞬态,每个服务都有自己的实例,因此永远不会出现范围/共享问题。
标签: c# asp.net-core .net-core dependency-injection