ResolutionContext
Represents information about the actual resolution flow.
using Stashbox.Entity;
using Stashbox.Utils;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace Stashbox.Resolution
{
public class ResolutionContext
{
private HashTree<Type, HashTree<object, Expression>> expressionOverrides;
private HashTree<Type, Type> currentlyDecoratingTypes;
private HashTree<bool> circularDependencyBarrier;
public bool NullResultAllowed { get; set; }
public ParameterExpression CurrentScopeParameter { get; set; }
internal IContainerContext RequestInitiatorContainerContext { get; set; }
internal IContainerContext CurrentContainerContext { get; set; }
internal HashTree<Expression> ExpressionCache { get; set; }
internal HashTree<Func<IResolutionScope, object>> FactoryCache { get; set; }
internal List<Expression> SingleInstructions { get; set; }
internal HashTree<ParameterExpression> DefinedVariables { get; set; }
internal bool ShouldCacheFactoryDelegate { get; set; }
internal List<object> ScopeNames { get; set; }
internal List<KeyValue<bool, ParameterExpression>[]> ParameterExpressions { get; set; }
internal static ResolutionContext New(List<object> initialScopeNames, IContainerContext currentContainerContext, bool nullResultAllowed = false, HashTree<Type, HashTree<object, Expression>> dependencyOverrides = null)
{
return new ResolutionContext(initialScopeNames, currentContainerContext, nullResultAllowed, dependencyOverrides);
}
private ResolutionContext(List<object> initialScopeNames, IContainerContext currentContainerContext, bool nullResultAllowed, HashTree<Type, HashTree<object, Expression>> dependencyOverrides)
{
DefinedVariables = HashTree<ParameterExpression>.Empty;
SingleInstructions = new List<Expression>();
expressionOverrides = (dependencyOverrides ?? HashTree<Type, HashTree<object, Expression>>.Empty);
currentlyDecoratingTypes = HashTree<Type, Type>.Empty;
NullResultAllowed = nullResultAllowed;
CurrentScopeParameter = Constants.ResolutionScopeParameter;
ParameterExpressions = new List<KeyValue<bool, ParameterExpression>[]>();
ScopeNames = initialScopeNames;
circularDependencyBarrier = HashTree<bool>.Empty;
ShouldCacheFactoryDelegate = (dependencyOverrides == null);
ExpressionCache = HashTree<Expression>.Empty;
FactoryCache = HashTree<Func<IResolutionScope, object>>.Empty;
CurrentContainerContext = currentContainerContext;
}
internal ResolutionContext()
{
}
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 bool IsCurrentlyDecorating(Type type)
{
return currentlyDecoratingTypes.GetOrDefault(type) != (Type)null;
}
internal void AddCurrentlyDecoratingType(Type type)
{
currentlyDecoratingTypes.Add(type, type);
}
internal void ClearCurrentlyDecoratingType(Type type)
{
currentlyDecoratingTypes.Add(type, null);
}
internal Expression GetExpressionOverrideOrDefault(Type type, object name = null)
{
return expressionOverrides.GetOrDefault(type)?.GetOrDefault(name ?? type);
}
internal void SetExpressionOverride(Type type, Expression expression)
{
HashTree<object, Expression> orDefault = expressionOverrides.GetOrDefault(type);
if (orDefault != null)
orDefault.Add(type, expression);
else
expressionOverrides.Add(type, new HashTree<object, Expression>(type, expression));
}
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 void AddParameterExpressions(ParameterExpression[] parameterExpressions)
{
int num = parameterExpressions.Length;
KeyValue<bool, ParameterExpression>[] array = new KeyValue<bool, ParameterExpression>[num];
for (int i = 0; i < num; i++) {
array[i] = new KeyValue<bool, ParameterExpression>(false, parameterExpressions[i]);
}
ParameterExpressions.Add(array);
}
internal void SetCircularDependencyBarrier(int key, bool value)
{
circularDependencyBarrier.Add(key, value);
}
internal bool GetCircularDependencyBarrier(int key)
{
return circularDependencyBarrier.GetOrDefault(key);
}
internal ResolutionContext Clone(IContainerContext requestInitiatorContext = null, IContainerContext currentContainerContext = null, KeyValue<object, ParameterExpression> scopeParameter = null)
{
if (scopeParameter != null)
ScopeNames.Add(scopeParameter.Key);
ResolutionContext resolutionContext = Clone();
resolutionContext.CurrentScopeParameter = ((scopeParameter == null) ? CurrentScopeParameter : scopeParameter.Value);
resolutionContext.RequestInitiatorContainerContext = (requestInitiatorContext ?? RequestInitiatorContainerContext);
resolutionContext.CurrentContainerContext = (currentContainerContext ?? CurrentContainerContext);
return resolutionContext;
}
internal ResolutionContext Clone()
{
ResolutionContext resolutionContext = Cloner<ResolutionContext>.Clone(this);
resolutionContext.DefinedVariables = HashTree<ParameterExpression>.Empty;
resolutionContext.SingleInstructions = new List<Expression>();
return resolutionContext;
}
}
}