Stashbox by Peter Csajtai

<PackageReference Include="Stashbox" Version="4.0.0-preview-662" />

 LifetimeDescriptor

public abstract class LifetimeDescriptor
Represents a lifetime descriptor.
using Stashbox.Exceptions; using Stashbox.Expressions; using Stashbox.Registration; using Stashbox.Resolution; using System; using System.Linq.Expressions; namespace Stashbox.Lifetime { public abstract class LifetimeDescriptor { private protected virtual bool StoreResultInLocalVariable { get; } protected virtual int LifeSpan { get; } protected string Name { get; } protected LifetimeDescriptor() { Name = GetType().Name; } internal Expression ApplyLifetime(ServiceRegistration serviceRegistration, ResolutionContext resolutionContext, Type requestedType) { if (resolutionContext.CurrentContainerContext.ContainerConfiguration.LifetimeValidationEnabled && LifeSpan > 0) { if (resolutionContext.CurrentLifeSpan > LifeSpan) throw new LifetimeValidationFailedException(serviceRegistration.ImplementationType, $"""{serviceRegistration.ImplementationType}""{Name}""{LifeSpan}""" + "is shorter than its direct or indirect parent's " + resolutionContext.NameOfServiceLifeSpanValidatingAgainst + "." + Environment.NewLine + "This could lead to incidental lifetime promotions with longer life-span, it's recommended to double check your lifetime configurations."); resolutionContext = resolutionContext.BeginLifetimeValidationContext(LifeSpan, $"{serviceRegistration.ImplementationType}""{Name}""{LifeSpan}"""); } if (!StoreResultInLocalVariable) return BuildLifetimeAppliedExpression(serviceRegistration, resolutionContext, requestedType); ParameterExpression knownVariableOrDefault = resolutionContext.GetKnownVariableOrDefault(serviceRegistration.RegistrationId); if (knownVariableOrDefault != null) return knownVariableOrDefault; Expression expression = BuildLifetimeAppliedExpression(serviceRegistration, resolutionContext, requestedType); if (expression == null) return null; knownVariableOrDefault = requestedType.AsVariable(null); resolutionContext.AddDefinedVariable(serviceRegistration.RegistrationId, knownVariableOrDefault); resolutionContext.AddInstruction(knownVariableOrDefault.AssignTo(expression)); return knownVariableOrDefault; } private protected abstract Expression BuildLifetimeAppliedExpression(ServiceRegistration serviceRegistration, ResolutionContext resolutionContext, Type requestedType); private protected static Expression GetExpressionForRegistration(ServiceRegistration serviceRegistration, ResolutionContext resolutionContext, Type requestedType) { if (!IsRegistrationOutputCacheable(serviceRegistration, resolutionContext)) return ExpressionBuilder.BuildExpressionForRegistration(serviceRegistration, resolutionContext, requestedType); Expression cachedExpression = resolutionContext.GetCachedExpression(serviceRegistration.RegistrationId); if (cachedExpression != null) return cachedExpression; cachedExpression = ExpressionBuilder.BuildExpressionForRegistration(serviceRegistration, resolutionContext, requestedType); resolutionContext.CacheExpression(serviceRegistration.RegistrationId, cachedExpression); return cachedExpression; } private protected static bool IsRegistrationOutputCacheable(ServiceRegistration serviceRegistration, ResolutionContext resolutionContext) { if (!serviceRegistration.IsDecorator && resolutionContext.FactoryDelegateCacheEnabled && resolutionContext.PerResolutionRequestCacheEnabled) return serviceRegistration.RegistrationType != RegistrationType.OpenGeneric; return false; } } }