Last active
September 9, 2023 20:35
-
-
Save waynebrantley/b4a9c3e6161c4edbc47bece6f492123a to your computer and use it in GitHub Desktop.
Scrutor functazure function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static bool TryDecorate(this IServiceCollection services, DecorationStrategy strategy, bool useFactory) | |
{ | |
if (!useFactory) | |
return services.TryDecorate(strategy); | |
var decorated = false; | |
for (var i = services.Count - 1; i >= 0; i--) | |
{ | |
var serviceDescriptor = services[i]; | |
if (serviceDescriptor.ServiceType is DecoratedType) | |
{ | |
continue; // Service has already been decorated. | |
} | |
if (!strategy.CanDecorate(serviceDescriptor.ServiceType)) | |
{ | |
continue; // Unable to decorate using the specified strategy. | |
} | |
var decoratedType = new DecoratedType(serviceDescriptor.ServiceType); | |
// Insert decorated | |
services.Add(serviceDescriptor.WithDecoratedTypeNext(decoratedType)); | |
// Replace decorator | |
services[i] = serviceDescriptor.WithImplementationFactory(strategy.CreateDecorator(decoratedType)); | |
decorated = true; | |
} | |
return decorated; | |
} | |
public static ServiceDescriptor WithImplementationFactory(this ServiceDescriptor descriptor, Func<IServiceProvider, object> implementationFactory) => | |
new(descriptor.ServiceType, implementationFactory, descriptor.Lifetime); | |
public static ServiceDescriptor WithDecoratedTypeNext(this ServiceDescriptor descriptor, DecoratedType serviceType) => descriptor switch | |
{ | |
{ ImplementationType: not null } => new ServiceDescriptor(serviceType, descriptor.ImplementationType.ToFactory2(), descriptor.Lifetime), | |
{ ImplementationFactory: not null } => new ServiceDescriptor(serviceType, descriptor.ImplementationFactory, descriptor.Lifetime), | |
{ ImplementationInstance: not null } => new ServiceDescriptor(serviceType, descriptor.ImplementationInstance), | |
_ => throw new ArgumentException($"No implementation factory or instance or type found for {descriptor.ServiceType}.", nameof(descriptor)) | |
}; | |
private static Func<IServiceProvider, object> ToFactory2(this Type serviceType) | |
{ | |
return new Cache(serviceType).Create; | |
} | |
public class Cache | |
{ | |
private readonly Func<ObjectFactory> _createActivator; | |
private ObjectFactory? _activator; | |
private bool _initialized; | |
private object? _lock; | |
public Cache(Type type) | |
{ | |
_createActivator = () => ActivatorUtilities.CreateFactory(type, Array.Empty<Type>()); | |
} | |
public ObjectFactory Activator => LazyInitializer.EnsureInitialized( | |
ref _activator, | |
ref _initialized, | |
ref _lock!, | |
_createActivator)!; | |
public object Create(IServiceProvider services) => Activator(services, Array.Empty<object>()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment