Skip to content
This repository has been archived by the owner on Nov 2, 2018. It is now read-only.

Commit

Permalink
Staticaly cache parts of the trees
Browse files Browse the repository at this point in the history
  • Loading branch information
pakrym committed Jul 13, 2016
1 parent dfdffde commit d68ced6
Showing 1 changed file with 29 additions and 34 deletions.
Expand Up @@ -20,12 +20,21 @@ internal class CallSiteExpressionBuilder : CallSiteVisitor<ParameterExpression,
private static readonly MethodInfo CallSiteRuntimeResolverResolve =
GetMethodInfo<Func<CallSiteRuntimeResolver, IServiceCallSite, ServiceProvider, object>>((r, c, p) => r.Resolve(c, p));

private readonly ParameterExpression _providerParameter = Expression.Parameter(typeof(ServiceProvider));
private readonly CallSiteRuntimeResolver _runtimeResolver;
private static readonly ParameterExpression ProviderParameter = Expression.Parameter(typeof(ServiceProvider));
private static readonly ParameterExpression ResolvedServices = Expression.Variable(typeof(IDictionary<object, object>),
ProviderParameter.Name + "resolvedServices");

private static readonly BinaryExpression ResolvedServicesVariableAssignment =
Expression.Assign(ResolvedServices,
Expression.Property(ProviderParameter, nameof(ServiceProvider.ResolvedServices)));

private ParameterExpression _resolvedServices;
private LambdaExpression _captureDisposable;
private BinaryExpression _resolvedServicesVariableAssignment;
private static readonly ParameterExpression CaptureDisposableParameter = Expression.Parameter(typeof(object));
private static readonly LambdaExpression CaptureDisposable = Expression.Lambda(
Expression.Call(ProviderParameter, CaptureDisposableMethodInfo, CaptureDisposableParameter),
CaptureDisposableParameter);

private readonly CallSiteRuntimeResolver _runtimeResolver;
private bool _requiresResolvedServices;

public CallSiteExpressionBuilder(CallSiteRuntimeResolver runtimeResolver)
{
Expand All @@ -38,26 +47,26 @@ public CallSiteExpressionBuilder(CallSiteRuntimeResolver runtimeResolver)

public Expression<Func<ServiceProvider, object>> Build(IServiceCallSite callSite)
{
var serviceExpression = VisitCallSite(callSite, _providerParameter);
var serviceExpression = VisitCallSite(callSite, ProviderParameter);

List<Expression> body = new List<Expression>();
if (_resolvedServicesVariableAssignment != null)
if (_requiresResolvedServices)
{
body.Add(_resolvedServicesVariableAssignment);
body.Add(ResolvedServicesVariableAssignment);
}
if (_resolvedServices != null)
if (_requiresResolvedServices)
{
serviceExpression = Lock(serviceExpression, _resolvedServices);
serviceExpression = Lock(serviceExpression, ResolvedServices);
}
body.Add(serviceExpression);

var variables = _resolvedServices != null
? new[] { _resolvedServices }
var variables = _requiresResolvedServices
? new[] { ResolvedServices }
: Enumerable.Empty<ParameterExpression>();

return Expression.Lambda<Func<ServiceProvider, object>>(
Expression.Block(variables, body),
_providerParameter);
ProviderParameter);
}

protected override Expression VisitSingleton(SingletonCallSite singletonCallSite, ParameterExpression provider)
Expand Down Expand Up @@ -186,35 +195,21 @@ private static MethodInfo GetMethodInfo<T>(Expression<T> expr)

public Expression GetCaptureDisposable(ParameterExpression provider)
{
if (_captureDisposable == null)
if (provider != ProviderParameter)
{
var parameter = Expression.Parameter(typeof(object));
_captureDisposable = Expression.Lambda(
Expression.Call(provider, CaptureDisposableMethodInfo, parameter), parameter);
throw new NotSupportedException("GetCaptureDisposable call is supported only for main provider");
}

return _captureDisposable;
return CaptureDisposable;
}

public Expression GetResolvedServices(ParameterExpression provider)
{
if (provider != _providerParameter)
{
throw new NotSupportedException("Resolved services call is supported only for main provider");
}
if (_resolvedServices == null)
if (provider != ProviderParameter)
{
var resolvedServicesExpression = Expression.Property(
provider,
nameof(ServiceProvider.ResolvedServices));

_resolvedServices = Expression.Variable(typeof(IDictionary<object, object>),
provider.Name + "resolvedServices");
_resolvedServicesVariableAssignment = Expression.Assign(_resolvedServices,
resolvedServicesExpression);
throw new NotSupportedException("GetResolvedServices call is supported only for main provider");
}

return _resolvedServices;
_requiresResolvedServices = true;
return ResolvedServices;
}

private static Expression Lock(Expression body, Expression syncVariable)
Expand Down

0 comments on commit d68ced6

Please sign in to comment.