Stashbox by Peter Csajtai

<PackageReference Include="Stashbox" Version="3.1.0-preview-537" />

 ResolutionContext

public class ResolutionContext
Represents information about the actual resolution flow.
using Stashbox.Entity; using Stashbox.Utils; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; namespace Stashbox.Resolution { public class ResolutionContext { private readonly HashTree<Expression> expressionCache; private readonly HashTree<Func<IResolutionScope, object>> factoryCache; private readonly HashTree<Type, HashTree<object, Expression>> expressionOverrides; private readonly HashTree<Type, Type> currentlyDecoratingTypes; private readonly HashTree<bool> circularDependencyBarrier; public bool NullResultAllowed { get; } public ParameterExpression CurrentScopeParameter { get; set; } internal IContainerContext RequestInitiatorContainerContext { get; set; } internal IContainerContext CurrentContainerContext { get; set; } internal ExpandableArray<Expression> SingleInstructions { get; set; } internal HashTree<ParameterExpression> DefinedVariables { get; set; } internal bool ExpressionCacheEnabled { get; set; } internal bool FactoryDelegateCacheEnabled { get; set; } internal ExpandableArray<object> ScopeNames { get; } internal ExpandableArray<KeyValue<bool, ParameterExpression>[]> ParameterExpressions { get; } internal ResolutionContext(IEnumerable<object> initialScopeNames, IContainerContext currentContainerContext, bool nullResultAllowed = false, HashTree<Type, HashTree<object, Expression>> dependencyOverrides = null) { DefinedVariables = new HashTree<ParameterExpression>(); SingleInstructions = new ExpandableArray<Expression>(); expressionOverrides = (dependencyOverrides ?? new HashTree<Type, HashTree<object, Expression>>()); currentlyDecoratingTypes = new HashTree<Type, Type>(); NullResultAllowed = nullResultAllowed; CurrentScopeParameter = Constants.ResolutionScopeParameter; ParameterExpressions = new ExpandableArray<KeyValue<bool, ParameterExpression>[]>(); ScopeNames = ExpandableArray<object>.FromEnumerable(initialScopeNames); circularDependencyBarrier = new HashTree<bool>(); expressionCache = new HashTree<Expression>(); factoryCache = new HashTree<Func<IResolutionScope, object>>(); FactoryDelegateCacheEnabled = (dependencyOverrides == null); CurrentContainerContext = currentContainerContext; } 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(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 bool IsCurrentlyDecorating(Type type) { return currentlyDecoratingTypes.GetOrDefault(type, true) != (Type)null; } internal void AddCurrentlyDecoratingType(Type type) { currentlyDecoratingTypes.Add(type, type, true); } internal void ClearCurrentlyDecoratingType(Type type) { currentlyDecoratingTypes.Add(type, null, true); } internal Expression GetExpressionOverrideOrDefault(Type type, object name = null) { return expressionOverrides.GetOrDefault(type, true)?.GetOrDefault(name ?? type, false); } internal void SetExpressionOverride(Type type, Expression expression) { HashTree<object, Expression> orDefault = expressionOverrides.GetOrDefault(type, true); if (orDefault != null) orDefault.Add(type, expression, true); else expressionOverrides.Add(type, new HashTree<object, Expression>(type, expression), true); } internal void AddParameterExpressions(IEnumerable<ParameterExpression> parameterExpressions) { ParameterExpressions.Add((from p in parameterExpressions select new KeyValue<bool, ParameterExpression>(false, p)).CastToArray()); ExpressionCacheEnabled = false; } internal void SetCircularDependencyBarrier(int key, bool value) { circularDependencyBarrier.Add(key, value); } internal bool GetCircularDependencyBarrier(int key) { return circularDependencyBarrier.GetOrDefault(key); } internal ResolutionContext BeginCrossContainerContext(IContainerContext requestInitiatorContext, IContainerContext currentContainerContext) { ResolutionContext resolutionContext = Clone(); resolutionContext.RequestInitiatorContainerContext = requestInitiatorContext; resolutionContext.CurrentContainerContext = 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 HashTree<ParameterExpression>(); resolutionContext.SingleInstructions = new ExpandableArray<Expression>(); return resolutionContext; } private ResolutionContext Clone() { return (ResolutionContext)MemberwiseClone(); } } }