Stashbox by Peter Csajtai

<PackageReference Include="Stashbox" Version="5.9.0-preview-803" />

 ServiceRegistrator

static class ServiceRegistrator
using Stashbox.Lifetime; using Stashbox.Utils.Data; using System; using System.Collections.Generic; 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 = new OpenGenericRegistration(serviceRegistration); PreProcessRegistration(containerContext, serviceRegistration); if (serviceRegistration.Options.TryGet(RegistrationOption.AdditionalServiceTypes, out object value)) { ExpandableArray<Type> expandableArray = value as ExpandableArray<Type>; if (expandableArray != null) { foreach (Type item in expandableArray.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 = new OpenGenericRegistration(serviceRegistration); PreProcessRegistration(containerContext, serviceRegistration); if (serviceRegistration.Options.TryGet(RegistrationOption.AdditionalServiceTypes, out object value)) { ExpandableArray<Type> expandableArray = value as ExpandableArray<Type>; if (expandableArray != null) { foreach (Type item in expandableArray.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) { if (serviceRegistration.Options.TryGet(RegistrationOption.RegistrationTypeOptions, out object value)) { InstanceOptions instanceOptions = value as InstanceOptions; if (instanceOptions != null) { PreProcessExistingInstanceIfNeeded(containerContext, instanceOptions.ExistingInstance, serviceRegistration.Options.IsOn(RegistrationOption.IsLifetimeExternallyOwned), serviceRegistration.Options.GetOrDefault<Action<object>>(RegistrationOption.Finalizer), serviceRegistration.ImplementationType); if (instanceOptions.IsWireUp) serviceRegistration.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); } } } }