ServiceRegistration
Represents a service registration.
using Stashbox.Configuration;
using Stashbox.Lifetime;
using Stashbox.Resolution;
using Stashbox.Utils.Data;
using System;
using System.Linq;
using System.Reflection;
using System.Threading;
namespace Stashbox.Registration
{
public class ServiceRegistration
{
private static int globalRegistrationOrder;
private readonly ContainerConfiguration containerConfiguration;
private readonly object namedScopeRestrictionIdentifier;
public Type ImplementationType { get; }
public RegistrationContext RegistrationContext { get; }
public int RegistrationId { get; set; }
public object SynchronizationObject { get; }
public bool IsDecorator { get; }
public RegistrationType RegistrationType { get; }
internal TypeInfo ImplementationTypeInfo { get; }
internal bool IsResolvableByUnnamedRequest { get; }
internal bool HasScopeName { get; }
internal bool HasCondition { get; }
internal object RegistrationDiscriminator { get; }
internal ServiceRegistration(Type implementationType, RegistrationType registrationType, ContainerConfiguration containerConfiguration, RegistrationContext registrationContext, bool isDecorator)
{
this.containerConfiguration = containerConfiguration;
ImplementationType = implementationType;
ImplementationTypeInfo = implementationType.GetTypeInfo();
RegistrationContext = registrationContext;
IsDecorator = isDecorator;
RegistrationType = registrationType;
SynchronizationObject = new object();
IsResolvableByUnnamedRequest = (RegistrationContext.Name == null || containerConfiguration.NamedDependencyResolutionForUnNamedRequestsEnabled);
NamedScopeLifetime namedScopeLifetime = RegistrationContext.Lifetime as NamedScopeLifetime;
if (namedScopeLifetime != null) {
HasScopeName = true;
namedScopeRestrictionIdentifier = namedScopeLifetime.ScopeName;
}
HasCondition = ((object)RegistrationContext.TargetTypeCondition != null || RegistrationContext.ResolutionCondition != null || (RegistrationContext.AttributeConditions != null && RegistrationContext.AttributeConditions.Any()));
RegistrationId = ReserveRegistrationOrder();
RegistrationDiscriminator = ((containerConfiguration.RegistrationBehavior == Rules.RegistrationBehavior.PreserveDuplications) ? ((object)RegistrationId) : (RegistrationContext.Name ?? implementationType));
}
internal bool IsUsableForCurrentContext(TypeInformation typeInfo)
{
if (!HasParentTypeConditionAndMatch(typeInfo) && !HasAttributeConditionAndMatch(typeInfo))
return HasResolutionConditionAndMatch(typeInfo);
return true;
}
internal bool CanInjectIntoNamedScope(ExpandableArray<object> scopeNames)
{
return scopeNames.Last() == namedScopeRestrictionIdentifier;
}
internal ServiceRegistration Clone(Type implementationType, RegistrationType registrationType)
{
return new ServiceRegistration(implementationType, registrationType, containerConfiguration, RegistrationContext, IsDecorator);
}
internal void Replaces(ServiceRegistration serviceRegistration)
{
RegistrationId = serviceRegistration.RegistrationId;
}
private bool HasParentTypeConditionAndMatch(TypeInformation typeInfo)
{
if ((object)RegistrationContext.TargetTypeCondition != null && (object)typeInfo.ParentType != null)
return (object)RegistrationContext.TargetTypeCondition == typeInfo.ParentType;
return false;
}
private bool HasAttributeConditionAndMatch(TypeInformation typeInfo)
{
if (RegistrationContext.AttributeConditions != null && typeInfo.CustomAttributes != null)
return RegistrationContext.AttributeConditions.Intersect(from attribute in typeInfo.CustomAttributes
select attribute.GetType()).Any();
return false;
}
private bool HasResolutionConditionAndMatch(TypeInformation typeInfo)
{
if (RegistrationContext.ResolutionCondition != null)
return RegistrationContext.ResolutionCondition(typeInfo);
return false;
}
private static int ReserveRegistrationOrder()
{
return Interlocked.Increment(ref globalRegistrationOrder);
}
}
}