Stashbox by Peter Csajtai

<PackageReference Include="Stashbox" Version="5.12.0-preview-821" />

 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; using System.Runtime.CompilerServices; namespace Stashbox.Lifetime { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public abstract class LifetimeDescriptor { private protected virtual bool StoreResultInLocalVariable => false; protected virtual int LifeSpan => 0; protected string Name { get; } protected LifetimeDescriptor() { Name = GetType().Name; } [return: System.Runtime.CompilerServices.Nullable(2)] internal Expression ApplyLifetime(ServiceRegistration serviceRegistration, ResolutionContext resolutionContext, TypeInformation typeInformation) { 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, typeInformation); ParameterExpression orDefault = resolutionContext.DefinedVariables.GetOrDefault(serviceRegistration.RegistrationId); if (orDefault != null) return orDefault; Expression expression = BuildLifetimeAppliedExpression(serviceRegistration, resolutionContext, typeInformation); if (expression == null) return null; orDefault = typeInformation.Type.AsVariable(null); if (typeInformation.Type != expression.Type) expression = expression.ConvertTo(typeInformation.Type); resolutionContext.AddDefinedVariable(serviceRegistration.RegistrationId, orDefault); resolutionContext.AddInstruction(orDefault.AssignTo(expression)); return orDefault; } [return: System.Runtime.CompilerServices.Nullable(2)] private protected abstract Expression BuildLifetimeAppliedExpression(ServiceRegistration serviceRegistration, ResolutionContext resolutionContext, TypeInformation typeInformation); [return: System.Runtime.CompilerServices.Nullable(2)] private protected static Expression GetExpressionForRegistration(ServiceRegistration serviceRegistration, ResolutionContext resolutionContext, TypeInformation typeInformation) { if (!IsRegistrationOutputCacheable(serviceRegistration, resolutionContext)) return ExpressionBuilder.BuildExpressionForRegistration(serviceRegistration, resolutionContext, typeInformation); Expression orDefault = resolutionContext.ExpressionCache.GetOrDefault(serviceRegistration.RegistrationId); if (orDefault != null) return orDefault; orDefault = ExpressionBuilder.BuildExpressionForRegistration(serviceRegistration, resolutionContext, typeInformation); if (orDefault == null) return null; resolutionContext.CacheExpression(serviceRegistration.RegistrationId, orDefault); return orDefault; } private protected static bool IsRegistrationOutputCacheable(ServiceRegistration serviceRegistration, ResolutionContext resolutionContext) { if (!serviceRegistration.IsDecorator && resolutionContext.RequestConfiguration.FactoryDelegateCacheEnabled && resolutionContext.PerResolutionRequestCacheEnabled) return !(serviceRegistration is OpenGenericRegistration); return false; } } }