Stashbox by Peter Csajtai

<PackageReference Include="Stashbox" Version="5.4.0" />

 ServiceRegistrator

static class ServiceRegistrator
using Stashbox.Lifetime; using Stashbox.Registration.ServiceRegistrations; using System; using System.Linq; using System.Runtime.CompilerServices; namespace Stashbox.Registration { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] internal static class ServiceRegistrator { public static void Register(IContainerContext containerContext, ServiceRegistration serviceRegistration, Type serviceType) { if (serviceRegistration.ImplementationType.IsOpenGenericType()) serviceRegistration = RegistrationFactory.EnsureOpenGeneric(serviceRegistration); PreProcessRegistration(containerContext, serviceRegistration); ComplexRegistration complexRegistration = serviceRegistration as ComplexRegistration; if (complexRegistration != null && complexRegistration.AdditionalServiceTypes != null) { foreach (Type item in complexRegistration.AdditionalServiceTypes.Distinct()) { if (item.IsOpenGenericType()) RegisterInternal(containerContext, serviceRegistration, item.GetGenericTypeDefinition()); else RegisterInternal(containerContext, serviceRegistration, item); } } RegisterInternal(containerContext, serviceRegistration, serviceType); } public static void ReMap(IContainerContext containerContext, ServiceRegistration serviceRegistration, Type serviceType) { if (serviceRegistration.ImplementationType.IsOpenGenericType()) serviceRegistration = RegistrationFactory.EnsureOpenGeneric(serviceRegistration); PreProcessRegistration(containerContext, serviceRegistration); ComplexRegistration complexRegistration = serviceRegistration as ComplexRegistration; if (complexRegistration != null && complexRegistration.AdditionalServiceTypes != null) { foreach (Type item in complexRegistration.AdditionalServiceTypes.Distinct()) { ReMapInternal(containerContext, serviceRegistration, item); } } ReMapInternal(containerContext, serviceRegistration, serviceType); } private static void RegisterInternal(IContainerContext containerContext, ServiceRegistration serviceRegistration, Type serviceType) { if (serviceRegistration.IsDecorator) { containerContext.DecoratorRepository.AddDecorator(serviceType, serviceRegistration, false); containerContext.RootScope.InvalidateDelegateCache(); } else if (containerContext.RegistrationRepository.AddOrUpdateRegistration(serviceRegistration, serviceType)) { containerContext.RootScope.InvalidateDelegateCache(); } } private static void ReMapInternal(IContainerContext containerContext, ServiceRegistration serviceRegistration, Type serviceType) { if (serviceRegistration.IsDecorator) containerContext.DecoratorRepository.AddDecorator(serviceType, serviceRegistration, true); else containerContext.RegistrationRepository.AddOrReMapRegistration(serviceRegistration, serviceType); containerContext.RootScope.InvalidateDelegateCache(); } private static void PreProcessRegistration(IContainerContext containerContext, ServiceRegistration serviceRegistration) { InstanceRegistration instanceRegistration = serviceRegistration as InstanceRegistration; if (instanceRegistration != null) { PreProcessExistingInstanceIfNeeded(containerContext, instanceRegistration.ExistingInstance, instanceRegistration.IsLifetimeExternallyOwned, instanceRegistration.Finalizer, instanceRegistration.ImplementationType); if (instanceRegistration.IsWireUp) instanceRegistration.Lifetime = Lifetimes.Singleton; } } private static void PreProcessExistingInstanceIfNeeded(IContainerContext containerContext, [System.Runtime.CompilerServices.Nullable(2)] object instance, bool isLifetimeExternallyOwned, [System.Runtime.CompilerServices.Nullable(new byte[] { 2, 1 })] Action<object> finalizer, Type implementationType) { if (instance != null) { if (!isLifetimeExternallyOwned && implementationType.IsDisposable()) containerContext.RootScope.AddDisposableTracking(instance); if (finalizer != null) containerContext.RootScope.AddWithFinalizer(instance, finalizer); } } } }