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);
}
}
}
}