ServiceProviderFactory
Represents various ways for building IServiceProvider implementations.
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
namespace DotNext
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public static class ServiceProviderFactory
{
[System.Runtime.CompilerServices.Nullable(0)]
public sealed class Builder : ISupplier<IServiceProvider>
{
[System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2
})]
private readonly IDictionary<Type, object> services = new Dictionary<Type, object>();
public Builder Add<[System.Runtime.CompilerServices.Nullable(2)] TService>(TService service)
{
services.Add(typeof(TService), (object)service);
return this;
}
public IServiceProvider Build([System.Runtime.CompilerServices.Nullable(2)] IServiceProvider fallback = null)
{
if (services.Count == 0)
return fallback ?? Empty;
return new CachedServiceProvider(services, fallback);
}
public void Clear()
{
services.Clear();
}
IServiceProvider ISupplier<IServiceProvider>.Invoke()
{
return Build(null);
}
}
[System.Runtime.CompilerServices.NullableContext(0)]
private sealed class CompiledServiceProvider : IServiceProvider
{
[System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
1,
2,
2
})]
private readonly Func<Type, object[], object> resolver;
[System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})]
private readonly object[] services;
internal CompiledServiceProvider([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
1,
2,
2
})] Func<Type, object[], object> resolver, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})] object[] services)
{
this.services = services;
this.resolver = resolver;
}
[System.Runtime.CompilerServices.NullableContext(1)]
[return: System.Runtime.CompilerServices.Nullable(2)]
object IServiceProvider.GetService(Type serviceType)
{
return resolver(serviceType, services);
}
}
[System.Runtime.CompilerServices.Nullable(0)]
private sealed class DelegatingServiceProvider : IServiceProvider
{
[System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
1,
2,
1,
2
})]
private readonly Func<Type, object[], IServiceProvider, object> resolver;
[System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})]
private readonly object[] services;
private readonly IServiceProvider fallback;
internal DelegatingServiceProvider([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
1,
2,
1,
2
})] Func<Type, object[], IServiceProvider, object> resolver, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})] object[] services, IServiceProvider fallback)
{
this.resolver = resolver;
this.services = services;
this.fallback = fallback;
}
[return: System.Runtime.CompilerServices.Nullable(2)]
object IServiceProvider.GetService(Type serviceType)
{
return resolver(serviceType, services, fallback);
}
}
[System.Runtime.CompilerServices.NullableContext(2)]
[System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
2
})]
private sealed class CachedServiceProvider : Dictionary<Type, object>, IServiceProvider
{
private readonly IServiceProvider fallback;
internal CachedServiceProvider([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2
})] IDictionary<Type, object> services, IServiceProvider fallback)
: base(services)
{
this.fallback = fallback;
}
internal CachedServiceProvider(IServiceProvider fallback, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
0,
1,
2
})] params KeyValuePair<Type, object>[] services)
: base((IEnumerable<KeyValuePair<Type, object>>)services)
{
this.fallback = fallback;
}
internal CachedServiceProvider(int capacity, IServiceProvider fallback)
: base(capacity)
{
this.fallback = fallback;
}
[System.Runtime.CompilerServices.NullableContext(1)]
[return: System.Runtime.CompilerServices.Nullable(2)]
object IServiceProvider.GetService(Type serviceType)
{
if (!TryGetValue(serviceType, out object value))
return fallback?.GetService(serviceType);
return value;
}
}
[System.Runtime.CompilerServices.NullableContext(0)]
private sealed class CachedServiceProvider<T> : IServiceProvider where T : struct, ITuple
{
[System.Runtime.CompilerServices.Nullable(1)]
private readonly Type[] serviceTypes;
[System.Runtime.CompilerServices.Nullable(2)]
private readonly IServiceProvider fallback;
private T tuple;
internal CachedServiceProvider(T tuple, [System.Runtime.CompilerServices.Nullable(2)] IServiceProvider fallback)
{
Type typeFromHandle = typeof(T);
serviceTypes = (typeFromHandle.IsConstructedGenericType ? typeFromHandle.GetGenericArguments() : Array.Empty<Type>());
this.tuple = tuple;
this.fallback = fallback;
}
[System.Runtime.CompilerServices.NullableContext(1)]
[return: System.Runtime.CompilerServices.Nullable(2)]
object IServiceProvider.GetService(Type serviceType)
{
int num = Array.IndexOf<Type>(serviceTypes, serviceType);
if (num < 0 || num >= tuple.Length)
return fallback?.GetService(serviceType);
return tuple[num];
}
}
[System.Runtime.CompilerServices.NullableContext(0)]
private sealed class EmptyProvider : IServiceProvider
{
[System.Runtime.CompilerServices.NullableContext(1)]
[return: System.Runtime.CompilerServices.Nullable(2)]
object IServiceProvider.GetService(Type serviceType)
{
return null;
}
}
public static readonly IServiceProvider Empty = new EmptyProvider();
private static CachedServiceProvider Create(this IReadOnlyList<Type> types, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})] object[] services, [System.Runtime.CompilerServices.Nullable(2)] IServiceProvider fallback)
{
CachedServiceProvider cachedServiceProvider = new CachedServiceProvider(types.Count, fallback);
for (int i = 0; i < types.Count; i++) {
cachedServiceProvider.Add(types[i], services[i]);
}
cachedServiceProvider.TrimExcess();
return cachedServiceProvider;
}
private static CachedServiceProvider Create(this IReadOnlyList<Type> types, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})] object[] services)
{
return types.Create(services, null);
}
private static SwitchExpression MakeResolver(IReadOnlyList<Type> types, ParameterExpression requestedType, ParameterExpression values, Expression defaultResolution)
{
List<SwitchCase> list = new List<SwitchCase>(types.Count);
for (int i = 0; i < types.Count; i++) {
list.Insert(i, Expression.SwitchCase(Expression.ArrayAccess(values, Expression.Constant(i)), Expression.Constant(types[i])));
}
return Expression.Switch(typeof(object), requestedType, defaultResolution, null, list);
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
1,
2,
2
})]
private static Func<Type, object[], object> CreateResolver(IReadOnlyList<Type> types)
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(Type));
ParameterExpression parameterExpression2 = Expression.Parameter(typeof(object[]));
return Expression.Lambda<Func<Type, object[], object>>(MakeResolver(types, parameterExpression, parameterExpression2, Expression.Constant(null, typeof(object))), false, new ParameterExpression[2] {
parameterExpression,
parameterExpression2
}).Compile();
}
private static CompiledServiceProvider Create([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
1,
2,
2
})] this Func<Type, object[], object> resolver, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})] object[] services)
{
return new CompiledServiceProvider(resolver, services);
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1
})]
public static Func<object[], IServiceProvider> CreateFactory(params Type[] types)
{
if (!RuntimeFeature.IsDynamicCodeCompiled)
return ((IReadOnlyList<Type>)types).Create;
return CreateResolver(types).Create;
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
1,
2,
1,
2
})]
private static Func<Type, object[], IServiceProvider, object> CreateDelegatingResolver(IReadOnlyList<Type> types)
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(Type));
ParameterExpression parameterExpression2 = Expression.Parameter(typeof(object[]));
ParameterExpression parameterExpression3 = Expression.Parameter(typeof(IServiceProvider));
return Expression.Lambda<Func<Type, object[], IServiceProvider, object>>(MakeResolver(types, parameterExpression, parameterExpression2, Expression.Call(parameterExpression3, "GetService", Array.Empty<Type>(), parameterExpression)), false, new ParameterExpression[3] {
parameterExpression,
parameterExpression2,
parameterExpression3
}).Compile();
}
private static DelegatingServiceProvider Create([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
1,
2,
1,
2
})] this Func<Type, object[], IServiceProvider, object> resolver, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})] object[] services, IServiceProvider fallback)
{
return new DelegatingServiceProvider(resolver, services, fallback);
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1,
1
})]
public static Func<object[], IServiceProvider, IServiceProvider> CreateDelegatingFactory(params Type[] types)
{
if (!RuntimeFeature.IsDynamicCodeCompiled)
return ((IReadOnlyList<Type>)types).Create;
return CreateDelegatingResolver(types).Create;
}
private static IServiceProvider Create<[System.Runtime.CompilerServices.Nullable(2)] T>([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1
})] this Func<object[], IServiceProvider> factory, T service)
{
return factory(new object[1] {
service
});
}
public static Func<T, IServiceProvider> CreateFactory<[System.Runtime.CompilerServices.Nullable(2)] T>()
{
return CreateFactory(typeof(T)).Create<T>;
}
private static IServiceProvider Create<[System.Runtime.CompilerServices.Nullable(2)] T>([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1,
1
})] this Func<object[], IServiceProvider, IServiceProvider> factory, T service, IServiceProvider fallback)
{
return factory(new object[1] {
service
}, fallback);
}
public static Func<T, IServiceProvider, IServiceProvider> CreateDelegatingFactory<[System.Runtime.CompilerServices.Nullable(2)] T>()
{
return CreateDelegatingFactory(typeof(T)).Create<T>;
}
private static IServiceProvider Create<[System.Runtime.CompilerServices.Nullable(2)] T1, [System.Runtime.CompilerServices.Nullable(2)] T2>([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1
})] this Func<object[], IServiceProvider> factory, T1 service1, T2 service2)
{
return factory(new object[2] {
service1,
service2
});
}
[System.Runtime.CompilerServices.NullableContext(2)]
[return: System.Runtime.CompilerServices.Nullable(1)]
public static Func<T1, T2, IServiceProvider> CreateFactory<T1, T2>()
{
return CreateFactory(typeof(T1), typeof(T2)).Create<T1, T2>;
}
private static IServiceProvider Create<[System.Runtime.CompilerServices.Nullable(2)] T1, [System.Runtime.CompilerServices.Nullable(2)] T2>([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1,
1
})] this Func<object[], IServiceProvider, IServiceProvider> factory, T1 service1, T2 service2, IServiceProvider fallback)
{
return factory(new object[2] {
service1,
service2
}, fallback);
}
[System.Runtime.CompilerServices.NullableContext(2)]
[return: System.Runtime.CompilerServices.Nullable(1)]
public static Func<T1, T2, IServiceProvider, IServiceProvider> CreateDelegatingFactory<T1, T2>()
{
return CreateDelegatingFactory(typeof(T1), typeof(T2)).Create<T1, T2>;
}
private static IServiceProvider Create<[System.Runtime.CompilerServices.Nullable(2)] T1, [System.Runtime.CompilerServices.Nullable(2)] T2, [System.Runtime.CompilerServices.Nullable(2)] T3>([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1
})] this Func<object[], IServiceProvider> factory, T1 service1, T2 service2, T3 service3)
{
return factory(new object[3] {
service1,
service2,
service3
});
}
[System.Runtime.CompilerServices.NullableContext(2)]
[return: System.Runtime.CompilerServices.Nullable(1)]
public static Func<T1, T2, T3, IServiceProvider> CreateFactory<T1, T2, T3>()
{
return CreateFactory(typeof(T1), typeof(T2), typeof(T3)).Create<T1, T2, T3>;
}
private static IServiceProvider Create<[System.Runtime.CompilerServices.Nullable(2)] T1, [System.Runtime.CompilerServices.Nullable(2)] T2, [System.Runtime.CompilerServices.Nullable(2)] T3>([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1,
1
})] this Func<object[], IServiceProvider, IServiceProvider> factory, T1 service1, T2 service2, T3 service3, IServiceProvider fallback)
{
return factory(new object[3] {
service1,
service2,
service3
}, fallback);
}
[System.Runtime.CompilerServices.NullableContext(2)]
[return: System.Runtime.CompilerServices.Nullable(1)]
public static Func<T1, T2, T3, IServiceProvider, IServiceProvider> CreateDelegatingFactory<T1, T2, T3>()
{
return CreateDelegatingFactory(typeof(T1), typeof(T2), typeof(T3)).Create<T1, T2, T3>;
}
private static IServiceProvider Create<[System.Runtime.CompilerServices.Nullable(2)] T1, [System.Runtime.CompilerServices.Nullable(2)] T2, [System.Runtime.CompilerServices.Nullable(2)] T3, [System.Runtime.CompilerServices.Nullable(2)] T4>([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1
})] this Func<object[], IServiceProvider> factory, T1 service1, T2 service2, T3 service3, T4 service4)
{
return factory(new object[4] {
service1,
service2,
service3,
service4
});
}
[System.Runtime.CompilerServices.NullableContext(2)]
[return: System.Runtime.CompilerServices.Nullable(1)]
public static Func<T1, T2, T3, T4, IServiceProvider> CreateFactory<T1, T2, T3, T4>()
{
return CreateFactory(typeof(T1), typeof(T2), typeof(T3), typeof(T4)).Create<T1, T2, T3, T4>;
}
private static IServiceProvider Create<[System.Runtime.CompilerServices.Nullable(2)] T1, [System.Runtime.CompilerServices.Nullable(2)] T2, [System.Runtime.CompilerServices.Nullable(2)] T3, [System.Runtime.CompilerServices.Nullable(2)] T4>([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1,
1
})] this Func<object[], IServiceProvider, IServiceProvider> factory, T1 service1, T2 service2, T3 service3, T4 service4, IServiceProvider fallback)
{
return factory(new object[4] {
service1,
service2,
service3,
service4
}, fallback);
}
[System.Runtime.CompilerServices.NullableContext(2)]
[return: System.Runtime.CompilerServices.Nullable(1)]
public static Func<T1, T2, T3, T4, IServiceProvider, IServiceProvider> CreateDelegatingFactory<T1, T2, T3, T4>()
{
return CreateDelegatingFactory(typeof(T1), typeof(T2), typeof(T3), typeof(T4)).Create<T1, T2, T3, T4>;
}
private static IServiceProvider Create<[System.Runtime.CompilerServices.Nullable(2)] T1, [System.Runtime.CompilerServices.Nullable(2)] T2, [System.Runtime.CompilerServices.Nullable(2)] T3, [System.Runtime.CompilerServices.Nullable(2)] T4, [System.Runtime.CompilerServices.Nullable(2)] T5>([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1
})] this Func<object[], IServiceProvider> factory, T1 service1, T2 service2, T3 service3, T4 service4, T5 service5)
{
return factory(new object[5] {
service1,
service2,
service3,
service4,
service5
});
}
[System.Runtime.CompilerServices.NullableContext(2)]
[return: System.Runtime.CompilerServices.Nullable(1)]
public static Func<T1, T2, T3, T4, T5, IServiceProvider> CreateFactory<T1, T2, T3, T4, T5>()
{
return CreateFactory(typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5)).Create<T1, T2, T3, T4, T5>;
}
private static IServiceProvider Create<[System.Runtime.CompilerServices.Nullable(2)] T1, [System.Runtime.CompilerServices.Nullable(2)] T2, [System.Runtime.CompilerServices.Nullable(2)] T3, [System.Runtime.CompilerServices.Nullable(2)] T4, [System.Runtime.CompilerServices.Nullable(2)] T5>([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2,
1,
1
})] this Func<object[], IServiceProvider, IServiceProvider> factory, T1 service1, T2 service2, T3 service3, T4 service4, T5 service5, IServiceProvider fallback)
{
return factory(new object[5] {
service1,
service2,
service3,
service4,
service5
}, fallback);
}
[System.Runtime.CompilerServices.NullableContext(2)]
[return: System.Runtime.CompilerServices.Nullable(1)]
public static Func<T1, T2, T3, T4, T5, IServiceProvider, IServiceProvider> CreateDelegatingFactory<T1, T2, T3, T4, T5>()
{
return CreateDelegatingFactory(typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5)).Create<T1, T2, T3, T4, T5>;
}
[System.Runtime.CompilerServices.NullableContext(0)]
[return: System.Runtime.CompilerServices.Nullable(1)]
public static IServiceProvider FromTuple<T>(T tuple, [System.Runtime.CompilerServices.Nullable(2)] IServiceProvider fallback = null) where T : struct, ITuple
{
return new CachedServiceProvider<T>(tuple, fallback);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
2
})]
private static KeyValuePair<Type, object> Registration<[System.Runtime.CompilerServices.Nullable(2)] T>(T service)
{
return new KeyValuePair<Type, object>(typeof(T), (object)service);
}
public static IServiceProvider Create<[System.Runtime.CompilerServices.Nullable(2)] T>(T service, [System.Runtime.CompilerServices.Nullable(2)] IServiceProvider fallback = null)
{
return new CachedServiceProvider(fallback, Registration(service));
}
public static IServiceProvider Create<[System.Runtime.CompilerServices.Nullable(2)] T1, [System.Runtime.CompilerServices.Nullable(2)] T2>(T1 service1, T2 service2, [System.Runtime.CompilerServices.Nullable(2)] IServiceProvider fallback = null)
{
return new CachedServiceProvider(fallback, Registration(service1), Registration(service2));
}
public static IServiceProvider Create<[System.Runtime.CompilerServices.Nullable(2)] T1, [System.Runtime.CompilerServices.Nullable(2)] T2, [System.Runtime.CompilerServices.Nullable(2)] T3>(T1 service1, T2 service2, T3 service3, [System.Runtime.CompilerServices.Nullable(2)] IServiceProvider fallback = null)
{
return new CachedServiceProvider(fallback, Registration(service1), Registration(service2), Registration(service3));
}
public static IServiceProvider Create<[System.Runtime.CompilerServices.Nullable(2)] T1, [System.Runtime.CompilerServices.Nullable(2)] T2, [System.Runtime.CompilerServices.Nullable(2)] T3, [System.Runtime.CompilerServices.Nullable(2)] T4>(T1 service1, T2 service2, T3 service3, T4 service4, [System.Runtime.CompilerServices.Nullable(2)] IServiceProvider fallback = null)
{
return new CachedServiceProvider(fallback, Registration(service1), Registration(service2), Registration(service3), Registration(service4));
}
public static IServiceProvider Create<[System.Runtime.CompilerServices.Nullable(2)] T1, [System.Runtime.CompilerServices.Nullable(2)] T2, [System.Runtime.CompilerServices.Nullable(2)] T3, [System.Runtime.CompilerServices.Nullable(2)] T4, [System.Runtime.CompilerServices.Nullable(2)] T5>(T1 service1, T2 service2, T3 service3, T4 service4, T5 service5, [System.Runtime.CompilerServices.Nullable(2)] IServiceProvider fallback = null)
{
return new CachedServiceProvider(fallback, Registration(service1), Registration(service2), Registration(service3), Registration(service4), Registration(service5));
}
}
}