Stashbox by Peter Csajtai

<PackageReference Include="Stashbox" Version="3.2.2-preview-581" />

 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 { private Tree<Expression> expressionCache; private readonly Tree<Func<IResolutionScope, object>> factoryCache; private readonly HashTree<object, Expression> expressionOverrides; private readonly Stashbox.Utils.Data.Stack<int> circularDependencyBarrier; internal IContainerContext RequestInitiatorContainerContext { get; } internal IResolutionStrategy ResolutionStrategy { get; } 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>> Decorators { 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 FactoryDelegateCacheEnabled { get; } internal ExpandableArray<object> ScopeNames { get; } public bool NullResultAllowed { get; } public bool IsRequestedFromRoot { get; } public ParameterExpression CurrentScopeParameter { get; set; } public IContainerContext CurrentContainerContext { get; set; } internal ResolutionContext(IEnumerable<object> initialScopeNames, IContainerContext currentContainerContext, IResolutionStrategy resolutionStrategy, bool isRequestedFromRoot, bool nullResultAllowed = false, HashTree<object, Expression> dependencyOverrides = null, ParameterExpression[] initialParameters = null) { DefinedVariables = new Tree<ParameterExpression>(); SingleInstructions = new ExpandableArray<Expression>(); Decorators = new ExpandableArray<Type, Stashbox.Utils.Data.Stack<ServiceRegistration>>(); expressionOverrides = dependencyOverrides; NullResultAllowed = nullResultAllowed; CurrentScopeParameter = Constants.ResolutionScopeParameter; ParameterExpressions = ((initialParameters != null) ? new ExpandableArray<Pair<bool, ParameterExpression>[]> { initialParameters.AsParameterPairs() } : new ExpandableArray<Pair<bool, ParameterExpression>[]>()); ScopeNames = initialScopeNames.AsExpandableArray(); circularDependencyBarrier = new Stashbox.Utils.Data.Stack<int>(); expressionCache = new Tree<Expression>(); factoryCache = new Tree<Func<IResolutionScope, object>>(); ResolutionStrategy = resolutionStrategy; IsRequestedFromRoot = isRequestedFromRoot; CurrentContainerContext = (RequestInitiatorContainerContext = currentContainerContext); bool flag2 = PerResolutionRequestCacheEnabled = (dependencyOverrides == null); FactoryDelegateCacheEnabled = flag2; } 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, object> factory) { factoryCache.Add(key, factory); } internal Func<IResolutionScope, object> GetCachedFactory(int key) { return factoryCache.GetOrDefault(key); } internal Expression GetExpressionOverrideOrDefault(Type type, object name = null) { return expressionOverrides?.GetOrDefault(name ?? type, false); } internal bool WeAreInCircle(int key) { return circularDependencyBarrier.Contains(key); } internal void PullOutCircularDependencyBarrier(int key) { circularDependencyBarrier.Add(key); } internal void LetDownCircularDependencyBarrier() { circularDependencyBarrier.Pop(); } internal ResolutionContext BeginCrossContainerContext(IContainerContext currentContainerContext) { ResolutionContext resolutionContext = Clone(); resolutionContext.CurrentContainerContext = currentContainerContext; resolutionContext.ShouldFallBackToRequestInitiatorContext = (resolutionContext.RequestInitiatorContainerContext != currentContainerContext); return resolutionContext; } internal ResolutionContext BeginNewScopeContext(KeyValue<object, ParameterExpression> scopeParameter) { ScopeNames.Add(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() { 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(); resolutionContext.Decorators = new ExpandableArray<Type, Stashbox.Utils.Data.Stack<ServiceRegistration>>(Decorators); resolutionContext.Decorators.AddOrUpdate(decoratingType, serviceRegistrations); 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(); } } }