ServiceRegistration
Represents a service registration.
using Stashbox.Configuration;
using Stashbox.Resolution;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
namespace Stashbox.Registration
{
public class ServiceRegistration
{
private static int globalRegistrationOrder;
private readonly ContainerConfiguration containerConfiguration;
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);
HasScopeName = (RegistrationContext.NamedScopeRestrictionIdentifier != null);
HasCondition = (RegistrationContext.TargetTypeCondition != (Type)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(IEnumerable<object> scopeNames)
{
return scopeNames.Last() == RegistrationContext.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 (RegistrationContext.TargetTypeCondition != (Type)null && typeInfo.ParentType != (Type)null)
return 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);
}
}
}