Stashbox by Peter Csajtai

<PackageReference Include="Stashbox" Version="5.1.0" />

 ResolutionContext

public class ResolutionContext
Represents information about the actual resolution flow.
using Stashbox.Registration; using Stashbox.Utils; using Stashbox.Utils.Data; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Runtime.CompilerServices; namespace Stashbox.Resolution { public class ResolutionContext { internal class PerRequestConfiguration { public bool RequiresRequestContext { get; set; } public bool FactoryDelegateCacheEnabled { get; set; } } private Tree<Expression> expressionCache; private readonly Tree<Func<IResolutionScope, IRequestContext, object>> factoryCache; private readonly HashTree<object, ConstantExpression> expressionOverrides; private readonly Stashbox.Utils.Data.Stack<int> circularDependencyBarrier; internal ExpandableArray<Expression> SingleInstructions { get; set; } internal Tree<ParameterExpression> DefinedVariables { get; set; } internal ExpandableArray<Pair<bool, ParameterExpression>[]> ParameterExpressions { get; set; } internal ExpandableArray<Type, Stashbox.Utils.Data.Stack<ServiceRegistration>> RemainingDecorators { get; set; } internal ExpandableArray<ServiceRegistration> CurrentDecorators { get; set; } internal int CurrentLifeSpan { get; set; } internal string NameOfServiceLifeSpanValidatingAgainst { get; set; } internal bool PerResolutionRequestCacheEnabled { get; set; } internal bool UnknownTypeCheckDisabled { get; set; } internal bool ShouldFallBackToRequestInitiatorContext { get; set; } internal bool IsTopRequest { get; set; } internal Stashbox.Utils.Data.Stack<object> ScopeNames { get; } internal IContainerContext RequestInitiatorContainerContext { get; } internal PerRequestConfiguration RequestConfiguration { get; } public bool NullResultAllowed { get; } public bool IsRequestedFromRoot { get; } public ParameterExpression CurrentScopeParameter { get; set; } public ParameterExpression RequestContextParameter { get; set; } public IContainerContext CurrentContainerContext { get; set; } private ResolutionContext(IEnumerable<object> initialScopeNames, IContainerContext currentContainerContext, bool isTopLevel, bool isRequestedFromRoot, bool nullResultAllowed, HashTree<object, ConstantExpression> dependencyOverrides, ParameterExpression[] initialParameters) { RequestConfiguration = new PerRequestConfiguration(); IsTopRequest = isTopLevel; DefinedVariables = new Tree<ParameterExpression>(); SingleInstructions = new ExpandableArray<Expression>(); RemainingDecorators = new ExpandableArray<Type, Stashbox.Utils.Data.Stack<ServiceRegistration>>(); CurrentDecorators = new ExpandableArray<ServiceRegistration>(); expressionOverrides = dependencyOverrides; NullResultAllowed = nullResultAllowed; CurrentScopeParameter = Constants.ResolutionScopeParameter; RequestContextParameter = Constants.RequestContextParameter; ParameterExpressions = ((initialParameters != null) ? new ExpandableArray<Pair<bool, ParameterExpression>[]> { initialParameters.AsParameterPairs() } : new ExpandableArray<Pair<bool, ParameterExpression>[]>()); ScopeNames = initialScopeNames.AsStack(); circularDependencyBarrier = new Stashbox.Utils.Data.Stack<int>(); expressionCache = new Tree<Expression>(); factoryCache = new Tree<Func<IResolutionScope, IRequestContext, object>>(); IsRequestedFromRoot = isRequestedFromRoot; CurrentContainerContext = (RequestInitiatorContainerContext = currentContainerContext); PerRequestConfiguration requestConfiguration = RequestConfiguration; bool factoryDelegateCacheEnabled = PerResolutionRequestCacheEnabled = (dependencyOverrides == null); requestConfiguration.FactoryDelegateCacheEnabled = factoryDelegateCacheEnabled; } public void AddInstruction(Expression instruction) { SingleInstructions.Add(instruction); } public void AddDefinedVariable(int key, ParameterExpression parameter) { DefinedVariables.Add(key, parameter); } public void AddDefinedVariable(ParameterExpression parameter) { DefinedVariables.Add(RuntimeHelpers.GetHashCode(parameter), parameter); } public ParameterExpression GetKnownVariableOrDefault(int key) { return DefinedVariables.GetOrDefault(key); } internal void CacheExpression(int key, Expression expression) { expressionCache.Add(key, expression); } internal Expression GetCachedExpression(int key) { return expressionCache.GetOrDefault(key); } internal void CacheFactory(int key, Func<IResolutionScope, IRequestContext, object> factory) { factoryCache.Add(key, factory); } internal Func<IResolutionScope, IRequestContext, object> GetCachedFactory(int key) { return factoryCache.GetOrDefault(key); } internal ConstantExpression GetExpressionOverrideOrDefault(Type type, object name = null) { return expressionOverrides?.GetOrDefaultByValue(name ?? type); } internal bool WeAreInCircle(int key) { return circularDependencyBarrier.Contains(key); } internal void PullOutCircularDependencyBarrier(int key) { circularDependencyBarrier.Add(key); } internal void LetDownCircularDependencyBarrier() { circularDependencyBarrier.Pop(); } internal static ResolutionContext BeginTopLevelContext(IEnumerable<object> initialScopeNames, IContainerContext currentContainerContext, bool isRequestedFromRoot, HashTree<object, ConstantExpression> dependencyOverrides = null, ParameterExpression[] initialParameters = null) { return new ResolutionContext(initialScopeNames, currentContainerContext, true, isRequestedFromRoot, false, dependencyOverrides, initialParameters); } internal static ResolutionContext BeginNullableTopLevelContext(IEnumerable<object> initialScopeNames, IContainerContext currentContainerContext, bool isRequestedFromRoot, HashTree<object, ConstantExpression> dependencyOverrides = null, ParameterExpression[] initialParameters = null) { return new ResolutionContext(initialScopeNames, currentContainerContext, true, isRequestedFromRoot, true, dependencyOverrides, initialParameters); } internal static ResolutionContext BeginValidationContext(IContainerContext currentContainerContext) { return new ResolutionContext(Constants.EmptyArray<object>(), currentContainerContext, true, false, false, null, null); } internal ResolutionContext BeginSubDependencyContext() { if (!IsTopRequest) return this; ResolutionContext resolutionContext = Clone(); resolutionContext.IsTopRequest = false; return resolutionContext; } internal ResolutionContext BeginCrossContainerContext(IContainerContext currentContainerContext) { ResolutionContext resolutionContext = Clone(); resolutionContext.CurrentContainerContext = currentContainerContext; resolutionContext.ShouldFallBackToRequestInitiatorContext = (resolutionContext.RequestInitiatorContainerContext != currentContainerContext); return resolutionContext; } internal ResolutionContext BeginNewScopeContext(ReadOnlyKeyValue<object, ParameterExpression> scopeParameter) { ScopeNames.PushBack(scopeParameter.Key); ResolutionContext resolutionContext = BeginSubGraph(); resolutionContext.CurrentScopeParameter = scopeParameter.Value; return resolutionContext; } internal ResolutionContext BeginSubGraph() { ResolutionContext resolutionContext = Clone(); resolutionContext.DefinedVariables = new Tree<ParameterExpression>(); resolutionContext.SingleInstructions = new ExpandableArray<Expression>(); resolutionContext.expressionCache = new Tree<Expression>(); return resolutionContext; } internal ResolutionContext BeginUnknownTypeCheckDisabledContext() { if (UnknownTypeCheckDisabled) return this; ResolutionContext resolutionContext = Clone(); resolutionContext.UnknownTypeCheckDisabled = true; return resolutionContext; } internal ResolutionContext BeginContextWithFunctionParameters(ParameterExpression[] parameterExpressions) { ResolutionContext resolutionContext = Clone(); resolutionContext.ParameterExpressions = new ExpandableArray<Pair<bool, ParameterExpression>[]>(ParameterExpressions) { parameterExpressions.AsParameterPairs() }; resolutionContext.PerResolutionRequestCacheEnabled = false; return resolutionContext; } internal ResolutionContext BeginDecoratingContext(Type decoratingType, Stashbox.Utils.Data.Stack<ServiceRegistration> serviceRegistrations) { ResolutionContext resolutionContext = Clone(); Stashbox.Utils.Data.Stack<ServiceRegistration> stack = new Stashbox.Utils.Data.Stack<ServiceRegistration>(serviceRegistrations); ServiceRegistration item = stack.Pop(); resolutionContext.CurrentDecorators = new ExpandableArray<ServiceRegistration>(CurrentDecorators) { item }; resolutionContext.RemainingDecorators = new ExpandableArray<Type, Stashbox.Utils.Data.Stack<ServiceRegistration>>(RemainingDecorators); resolutionContext.RemainingDecorators.AddOrUpdate(decoratingType, stack); return resolutionContext; } internal ResolutionContext BeginLifetimeValidationContext(int lifeSpan, string currentlyLifeSpanValidatingService) { ResolutionContext resolutionContext = Clone(); resolutionContext.CurrentLifeSpan = lifeSpan; resolutionContext.NameOfServiceLifeSpanValidatingAgainst = currentlyLifeSpanValidatingService; return resolutionContext; } private ResolutionContext Clone() { return (ResolutionContext)MemberwiseClone(); } } }