Reputation: 148524
I have 3 interfaces ( for singleton/scoped/transient) :
public interface ISingleton
{
}
class Singlet : ISingleton
{
}
public interface IScoped
{
}
class Scoped : IScoped
{
}
public interface Itransient
{
}
class Transient : Itransient
{
}
I register them as :
services.AddScoped<IScoped, Scoped>();
services.AddTransient<Itransient, Transient>();
services.AddSingleton<ISingleton, Singlet>();
If I try to inject scoped service to singleton , I should (and do) get an exception (I know the reason for this):
public interface ISingleton
{
}
class Singlet : ISingleton
{
public Singlet( IScoped sc)
{
}
}
Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: WebApplication2.ISingleton Lifetime: Singleton ImplementationType: WebApplication2.Singlet': Cannot consume scoped service 'WebApplication2.IScoped' from singleton 'WebApplication2.ISingleton'.)
But if I try to inject transient , I do not get an exception :
public interface ISingleton
{
}
class Singlet : ISingleton
{
public Singlet( Itransient tr)
{
}
}
Question:
Why does .net core forbids injecting a shorter lifetime (scoped) services raising an exception, while allowing transient to be injected to a singleton?
Upvotes: 7
Views: 2174
Reputation: 155015
I suggest reading this first: When are .NET Core dependency injected instances disposed?
(Preface: My answer assumes that service implementations never dispose of any injected services themselves.)
Why does .net core forbids injecting a shorter lifetime (scoped) services raising an exception, while allowing transient to be injected to a singleton?
IHost.Dispose()
)In short: the lifetime of a transient service is the same as the service it's injected into - not longer, not shorter. That's why it's allowed.
Whereas the lifetime of a scoped service is shorter than the root-scope/root-container's lifetime, and the root-scope/root-container is used for holding singleton instances, therefore a scoped service cannot be consumed by a singleton (more importantly it's because child scopes don't exist in the context of the root scope).
Upvotes: 11