ServiceDescriptor
Describes a service with its service type, implementation, and lifetime.
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
namespace Microsoft.Extensions.DependencyInjection
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
[DebuggerDisplay("{DebuggerToString(),nq}")]
public class ServiceDescriptor
{
[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)]
private Type _implementationType;
private object _implementationInstance;
private object _implementationFactory;
public ServiceLifetime Lifetime { get; }
[System.Runtime.CompilerServices.Nullable(2)]
public object ServiceKey {
[System.Runtime.CompilerServices.NullableContext(2)]
get;
}
public Type ServiceType { get; }
[System.Runtime.CompilerServices.Nullable(2)]
[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)]
public Type ImplementationType {
[System.Runtime.CompilerServices.NullableContext(2)]
get {
if (!IsKeyedService)
return _implementationType;
return null;
}
}
[System.Runtime.CompilerServices.Nullable(2)]
[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)]
public Type KeyedImplementationType {
[System.Runtime.CompilerServices.NullableContext(2)]
get {
if (!IsKeyedService)
ThrowNonKeyedDescriptor();
return _implementationType;
}
}
[System.Runtime.CompilerServices.Nullable(2)]
public object ImplementationInstance {
[System.Runtime.CompilerServices.NullableContext(2)]
get {
if (!IsKeyedService)
return _implementationInstance;
return null;
}
}
[System.Runtime.CompilerServices.Nullable(2)]
public object KeyedImplementationInstance {
[System.Runtime.CompilerServices.NullableContext(2)]
get {
if (!IsKeyedService)
ThrowNonKeyedDescriptor();
return _implementationInstance;
}
}
[System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})]
public Func<IServiceProvider, object> ImplementationFactory {
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})]
get {
if (!IsKeyedService)
return (Func<IServiceProvider, object>)_implementationFactory;
return null;
}
}
[System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
2,
1
})]
public Func<IServiceProvider, object, object> KeyedImplementationFactory {
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
2,
1
})]
get {
if (!IsKeyedService)
ThrowNonKeyedDescriptor();
return (Func<IServiceProvider, object, object>)_implementationFactory;
}
}
public bool IsKeyedService => ServiceKey != null;
public ServiceDescriptor(Type serviceType, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType, ServiceLifetime lifetime)
: this(serviceType, null, implementationType, lifetime)
{
}
public ServiceDescriptor(Type serviceType, [System.Runtime.CompilerServices.Nullable(2)] object serviceKey, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType, ServiceLifetime lifetime)
: this(serviceType, serviceKey, lifetime)
{
System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
_implementationType = implementationType;
}
public ServiceDescriptor(Type serviceType, object instance)
: this(serviceType, null, instance)
{
}
public ServiceDescriptor(Type serviceType, [System.Runtime.CompilerServices.Nullable(2)] object serviceKey, object instance)
: this(serviceType, serviceKey, ServiceLifetime.Singleton)
{
System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
System.ThrowHelper.ThrowIfNull(instance, "instance");
_implementationInstance = instance;
}
public ServiceDescriptor(Type serviceType, Func<IServiceProvider, object> factory, ServiceLifetime lifetime)
: this(serviceType, (object)null, lifetime)
{
System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
System.ThrowHelper.ThrowIfNull(factory, "factory");
_implementationFactory = factory;
}
public ServiceDescriptor(Type serviceType, [System.Runtime.CompilerServices.Nullable(2)] object serviceKey, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1
})] Func<IServiceProvider, object, object> factory, ServiceLifetime lifetime)
: this(serviceType, serviceKey, lifetime)
{
System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
System.ThrowHelper.ThrowIfNull(factory, "factory");
if (serviceKey == null) {
Func<IServiceProvider, object> func = (Func<IServiceProvider, object>)(_implementationFactory = (Func<IServiceProvider, object>)((IServiceProvider sp) => factory(sp, null)));
} else
_implementationFactory = factory;
}
private ServiceDescriptor(Type serviceType, object serviceKey, ServiceLifetime lifetime)
{
Lifetime = lifetime;
ServiceType = serviceType;
ServiceKey = serviceKey;
}
public override string ToString()
{
string str = string.Format("{0}: {1} {2}: {3} ", "ServiceType", ServiceType, "Lifetime", Lifetime);
if (IsKeyedService) {
str += string.Format("{0}: {1} ", "ServiceKey", ServiceKey);
if (KeyedImplementationType != (Type)null)
return str + string.Format("{0}: {1}", "KeyedImplementationType", KeyedImplementationType);
if (KeyedImplementationFactory != null)
return str + string.Format("{0}: {1}", "KeyedImplementationFactory", KeyedImplementationFactory.Method);
return str + string.Format("{0}: {1}", "KeyedImplementationInstance", KeyedImplementationInstance);
}
if (ImplementationType != (Type)null)
return str + string.Format("{0}: {1}", "ImplementationType", ImplementationType);
if (ImplementationFactory != null)
return str + string.Format("{0}: {1}", "ImplementationFactory", ImplementationFactory.Method);
return str + string.Format("{0}: {1}", "ImplementationInstance", ImplementationInstance);
}
internal Type GetImplementationType()
{
if (ServiceKey == null) {
if (ImplementationType != (Type)null)
return ImplementationType;
if (ImplementationInstance != null)
return ImplementationInstance.GetType();
if (ImplementationFactory != null)
return ImplementationFactory.GetType().GenericTypeArguments[1];
} else {
if (KeyedImplementationType != (Type)null)
return KeyedImplementationType;
if (KeyedImplementationInstance != null)
return KeyedImplementationInstance.GetType();
if (KeyedImplementationFactory != null)
return KeyedImplementationFactory.GetType().GenericTypeArguments[2];
}
return null;
}
public static ServiceDescriptor Transient<TService, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>() where TService : class where TImplementation : class, TService
{
return DescribeKeyed<TService, TImplementation>(null, ServiceLifetime.Transient);
}
public static ServiceDescriptor KeyedTransient<TService, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>([System.Runtime.CompilerServices.Nullable(2)] object serviceKey) where TService : class where TImplementation : class, TService
{
return DescribeKeyed<TService, TImplementation>(serviceKey, ServiceLifetime.Transient);
}
public static ServiceDescriptor Transient(Type service, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
{
System.ThrowHelper.ThrowIfNull(service, "service");
System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
return Describe(service, implementationType, ServiceLifetime.Transient);
}
public static ServiceDescriptor KeyedTransient(Type service, [System.Runtime.CompilerServices.Nullable(2)] object serviceKey, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
{
System.ThrowHelper.ThrowIfNull(service, "service");
System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
return DescribeKeyed(service, serviceKey, implementationType, ServiceLifetime.Transient);
}
public static ServiceDescriptor Transient<TService, TImplementation>(Func<IServiceProvider, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
{
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return Describe(typeof(TService), implementationFactory, ServiceLifetime.Transient);
}
public static ServiceDescriptor KeyedTransient<TService, TImplementation>([System.Runtime.CompilerServices.Nullable(2)] object serviceKey, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1
})] Func<IServiceProvider, object, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
{
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return DescribeKeyed(typeof(TService), serviceKey, implementationFactory, ServiceLifetime.Transient);
}
public static ServiceDescriptor Transient<TService>(Func<IServiceProvider, TService> implementationFactory) where TService : class
{
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return Describe(typeof(TService), implementationFactory, ServiceLifetime.Transient);
}
public static ServiceDescriptor KeyedTransient<TService>([System.Runtime.CompilerServices.Nullable(2)] object serviceKey, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1
})] Func<IServiceProvider, object, TService> implementationFactory) where TService : class
{
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return DescribeKeyed(typeof(TService), serviceKey, implementationFactory, ServiceLifetime.Transient);
}
public static ServiceDescriptor Transient(Type service, Func<IServiceProvider, object> implementationFactory)
{
System.ThrowHelper.ThrowIfNull(service, "service");
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return Describe(service, implementationFactory, ServiceLifetime.Transient);
}
public static ServiceDescriptor KeyedTransient(Type service, [System.Runtime.CompilerServices.Nullable(2)] object serviceKey, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1
})] Func<IServiceProvider, object, object> implementationFactory)
{
System.ThrowHelper.ThrowIfNull(service, "service");
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return DescribeKeyed(service, serviceKey, implementationFactory, ServiceLifetime.Transient);
}
public static ServiceDescriptor Scoped<TService, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>() where TService : class where TImplementation : class, TService
{
return DescribeKeyed<TService, TImplementation>(null, ServiceLifetime.Scoped);
}
public static ServiceDescriptor KeyedScoped<TService, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>([System.Runtime.CompilerServices.Nullable(2)] object serviceKey) where TService : class where TImplementation : class, TService
{
return DescribeKeyed<TService, TImplementation>(serviceKey, ServiceLifetime.Scoped);
}
public static ServiceDescriptor Scoped(Type service, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
{
return Describe(service, implementationType, ServiceLifetime.Scoped);
}
public static ServiceDescriptor KeyedScoped(Type service, [System.Runtime.CompilerServices.Nullable(2)] object serviceKey, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
{
return DescribeKeyed(service, serviceKey, implementationType, ServiceLifetime.Scoped);
}
public static ServiceDescriptor Scoped<TService, TImplementation>(Func<IServiceProvider, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
{
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return Describe(typeof(TService), implementationFactory, ServiceLifetime.Scoped);
}
public static ServiceDescriptor KeyedScoped<TService, TImplementation>([System.Runtime.CompilerServices.Nullable(2)] object serviceKey, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1
})] Func<IServiceProvider, object, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
{
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return DescribeKeyed(typeof(TService), serviceKey, implementationFactory, ServiceLifetime.Scoped);
}
public static ServiceDescriptor Scoped<TService>(Func<IServiceProvider, TService> implementationFactory) where TService : class
{
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return Describe(typeof(TService), implementationFactory, ServiceLifetime.Scoped);
}
public static ServiceDescriptor KeyedScoped<TService>([System.Runtime.CompilerServices.Nullable(2)] object serviceKey, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1
})] Func<IServiceProvider, object, TService> implementationFactory) where TService : class
{
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return DescribeKeyed(typeof(TService), serviceKey, implementationFactory, ServiceLifetime.Scoped);
}
public static ServiceDescriptor Scoped(Type service, Func<IServiceProvider, object> implementationFactory)
{
System.ThrowHelper.ThrowIfNull(service, "service");
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return Describe(service, implementationFactory, ServiceLifetime.Scoped);
}
public static ServiceDescriptor KeyedScoped(Type service, [System.Runtime.CompilerServices.Nullable(2)] object serviceKey, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1
})] Func<IServiceProvider, object, object> implementationFactory)
{
System.ThrowHelper.ThrowIfNull(service, "service");
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return DescribeKeyed(service, serviceKey, implementationFactory, ServiceLifetime.Scoped);
}
public static ServiceDescriptor Singleton<TService, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>() where TService : class where TImplementation : class, TService
{
return DescribeKeyed<TService, TImplementation>(null, ServiceLifetime.Singleton);
}
public static ServiceDescriptor KeyedSingleton<TService, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>([System.Runtime.CompilerServices.Nullable(2)] object serviceKey) where TService : class where TImplementation : class, TService
{
return DescribeKeyed<TService, TImplementation>(serviceKey, ServiceLifetime.Singleton);
}
public static ServiceDescriptor Singleton(Type service, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
{
System.ThrowHelper.ThrowIfNull(service, "service");
System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
return Describe(service, implementationType, ServiceLifetime.Singleton);
}
public static ServiceDescriptor KeyedSingleton(Type service, [System.Runtime.CompilerServices.Nullable(2)] object serviceKey, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
{
System.ThrowHelper.ThrowIfNull(service, "service");
System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
return DescribeKeyed(service, serviceKey, implementationType, ServiceLifetime.Singleton);
}
public static ServiceDescriptor Singleton<TService, TImplementation>(Func<IServiceProvider, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
{
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return Describe(typeof(TService), implementationFactory, ServiceLifetime.Singleton);
}
public static ServiceDescriptor KeyedSingleton<TService, TImplementation>([System.Runtime.CompilerServices.Nullable(2)] object serviceKey, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1
})] Func<IServiceProvider, object, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
{
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return DescribeKeyed(typeof(TService), serviceKey, implementationFactory, ServiceLifetime.Singleton);
}
public static ServiceDescriptor Singleton<TService>(Func<IServiceProvider, TService> implementationFactory) where TService : class
{
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return Describe(typeof(TService), implementationFactory, ServiceLifetime.Singleton);
}
public static ServiceDescriptor KeyedSingleton<TService>([System.Runtime.CompilerServices.Nullable(2)] object serviceKey, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1
})] Func<IServiceProvider, object, TService> implementationFactory) where TService : class
{
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return DescribeKeyed(typeof(TService), serviceKey, implementationFactory, ServiceLifetime.Singleton);
}
public static ServiceDescriptor Singleton(Type serviceType, Func<IServiceProvider, object> implementationFactory)
{
System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return Describe(serviceType, implementationFactory, ServiceLifetime.Singleton);
}
public static ServiceDescriptor KeyedSingleton(Type serviceType, [System.Runtime.CompilerServices.Nullable(2)] object serviceKey, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1
})] Func<IServiceProvider, object, object> implementationFactory)
{
System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
return DescribeKeyed(serviceType, serviceKey, implementationFactory, ServiceLifetime.Singleton);
}
public static ServiceDescriptor Singleton<TService>(TService implementationInstance) where TService : class
{
System.ThrowHelper.ThrowIfNull(implementationInstance, "implementationInstance");
return Singleton(typeof(TService), implementationInstance);
}
public static ServiceDescriptor KeyedSingleton<TService>([System.Runtime.CompilerServices.Nullable(2)] object serviceKey, TService implementationInstance) where TService : class
{
System.ThrowHelper.ThrowIfNull(implementationInstance, "implementationInstance");
return KeyedSingleton(typeof(TService), serviceKey, implementationInstance);
}
public static ServiceDescriptor Singleton(Type serviceType, object implementationInstance)
{
System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
System.ThrowHelper.ThrowIfNull(implementationInstance, "implementationInstance");
return new ServiceDescriptor(serviceType, implementationInstance);
}
public static ServiceDescriptor KeyedSingleton(Type serviceType, [System.Runtime.CompilerServices.Nullable(2)] object serviceKey, object implementationInstance)
{
System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
System.ThrowHelper.ThrowIfNull(implementationInstance, "implementationInstance");
return new ServiceDescriptor(serviceType, serviceKey, implementationInstance);
}
private static ServiceDescriptor DescribeKeyed<TService, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(object serviceKey, ServiceLifetime lifetime) where TService : class where TImplementation : class, TService
{
return DescribeKeyed(typeof(TService), serviceKey, typeof(TImplementation), lifetime);
}
public static ServiceDescriptor Describe(Type serviceType, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType, ServiceLifetime lifetime)
{
return new ServiceDescriptor(serviceType, implementationType, lifetime);
}
public static ServiceDescriptor DescribeKeyed(Type serviceType, [System.Runtime.CompilerServices.Nullable(2)] object serviceKey, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType, ServiceLifetime lifetime)
{
return new ServiceDescriptor(serviceType, serviceKey, implementationType, lifetime);
}
public static ServiceDescriptor Describe(Type serviceType, Func<IServiceProvider, object> implementationFactory, ServiceLifetime lifetime)
{
return new ServiceDescriptor(serviceType, implementationFactory, lifetime);
}
public static ServiceDescriptor DescribeKeyed(Type serviceType, [System.Runtime.CompilerServices.Nullable(2)] object serviceKey, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1
})] Func<IServiceProvider, object, object> implementationFactory, ServiceLifetime lifetime)
{
return new ServiceDescriptor(serviceType, serviceKey, implementationFactory, lifetime);
}
private string DebuggerToString()
{
string str = $"""{Lifetime}""{ServiceType.FullName}""";
if (!IsKeyedService) {
if (!(ImplementationType != (Type)null)) {
if (ImplementationFactory == null)
return str + $"""{ImplementationInstance}";
return str + $"""{ImplementationFactory.Method}";
}
return str + ", ImplementationType = \"" + ImplementationType.FullName + "\"";
}
str += $"""{ServiceKey}""";
if (!(KeyedImplementationType != (Type)null)) {
if (KeyedImplementationFactory == null)
return str + $"""{KeyedImplementationInstance}";
return str + $"""{KeyedImplementationFactory.Method}";
}
return str + ", KeyedImplementationType = \"" + KeyedImplementationType.FullName + "\"";
}
private static void ThrowNonKeyedDescriptor()
{
throw new InvalidOperationException(System.SR.NonKeyedDescriptorMisuse);
}
}
}