ServiceRegistration
Represents a service registration.
using Stashbox.Configuration;
using Stashbox.Lifetime;
using Stashbox.Resolution;
using System;
using System.Linq;
using System.Threading;
namespace Stashbox.Registration
{
public class ServiceRegistration
{
private static int globalRegistrationId;
private static int globalRegistrationOrder;
internal readonly bool IsResolvableByUnnamedRequest;
internal readonly bool HasScopeName;
internal readonly object NamedScopeRestrictionIdentifier;
internal readonly bool HasCondition;
internal readonly object RegistrationDiscriminator;
private protected readonly ContainerConfiguration Configuration;
public Type ImplementationType { get; }
public RegistrationContext RegistrationContext { get; }
public int RegistrationId { get; }
public int RegistrationOrder { get; set; }
public bool IsDecorator { get; }
public RegistrationType RegistrationType { get; }
internal ServiceRegistration(Type implementationType, RegistrationType registrationType, ContainerConfiguration containerConfiguration, RegistrationContext registrationContext, bool isDecorator)
{
Configuration = containerConfiguration;
ImplementationType = implementationType;
RegistrationContext = registrationContext;
IsDecorator = isDecorator;
RegistrationType = registrationType;
IsResolvableByUnnamedRequest = (RegistrationContext.Name == null || containerConfiguration.NamedDependencyResolutionForUnNamedRequestsEnabled);
NamedScopeLifetime namedScopeLifetime = RegistrationContext.Lifetime as NamedScopeLifetime;
if (namedScopeLifetime != null) {
HasScopeName = true;
NamedScopeRestrictionIdentifier = namedScopeLifetime.ScopeName;
}
HasCondition = (RegistrationContext.TargetTypeConditions.Length > 0 || RegistrationContext.ResolutionConditions.Length > 0 || RegistrationContext.AttributeConditions.Length > 0);
RegistrationId = ReserveRegistrationId();
RegistrationOrder = 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 void Replaces(ServiceRegistration serviceRegistration)
{
RegistrationOrder = serviceRegistration.RegistrationOrder;
}
private bool HasParentTypeConditionAndMatch(TypeInformation typeInfo)
{
if (RegistrationContext.TargetTypeConditions.Length > 0 && typeInfo.ParentType != (Type)null)
return RegistrationContext.TargetTypeConditions.Contains(typeInfo.ParentType);
return false;
}
private bool HasAttributeConditionAndMatch(TypeInformation typeInfo)
{
if (RegistrationContext.AttributeConditions.Length > 0 && 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.ResolutionConditions.Length == 0)
return false;
int length = RegistrationContext.ResolutionConditions.Length;
for (int i = 0; i < length; i++) {
if (RegistrationContext.ResolutionConditions[i](typeInfo))
return true;
}
return false;
}
private static int ReserveRegistrationId()
{
return Interlocked.Increment(ref globalRegistrationId);
}
private static int ReserveRegistrationOrder()
{
return Interlocked.Increment(ref globalRegistrationOrder);
}
}
}