/// <summary> /// Process expression result for compiling /// </summary> /// <param name="expressionContext"></param> /// <param name="parameters"></param> /// <param name="extraExpressions"></param> /// <returns></returns> protected virtual Expression ProcessExpressionResultForCompile(IActivationExpressionResult expressionContext, out ParameterExpression[] parameters, out Expression[] extraExpressions) { if (expressionContext.Request.InjectionContextRequired()) { AddInjectionContextExpression(expressionContext); } var finalExpression = expressionContext.Expression; if (!finalExpression.Type.IsByRef) { finalExpression = Expression.Convert(finalExpression, typeof(object)); } if (finalExpression.NodeType == ExpressionType.Convert && !expressionContext.Expression.Type.GetTypeInfo().IsValueType) { finalExpression = ((UnaryExpression)finalExpression).Operand; } parameters = expressionContext.ExtraParameters().ToArray(); extraExpressions = expressionContext.ExtraExpressions().ToArray(); return(finalExpression); }
/// <summary> /// Default constructor /// </summary> /// <param name="expressionResult"></param> public DynamicMethodGenerationRequest(IActivationExpressionResult expressionResult, Func <DynamicMethodGenerationRequest, Expression, bool> tryGenerateIL, ParameterExpression[] extraParameters) { ExpressionResult = expressionResult; TryGenerateIL = tryGenerateIL; ExtraParameters = extraParameters; ExpressionRequest = ExpressionResult.Request; }
/// <summary> /// Select the best strategy from collection to satisfy request /// </summary> /// <param name="collection"></param> /// <param name="scope"></param> /// <param name="request"></param> /// <returns></returns> protected virtual IActivationExpressionResult SelectStrategyFromCollection(IActivationStrategyCollection <ICompiledExportStrategy> collection, IInjectionScope scope, IActivationExpressionRequest request) { var filter = request.Filter; IActivationExpressionResult result = null; foreach (var strategy in collection.GetStrategies()) { if (filter != null && !filter(strategy)) { continue; } if (strategy.HasConditions) { var context = request.GetStaticInjectionContext(); if (!strategy.Conditions.All(condition => condition.MeetsCondition(strategy, context))) { continue; } } result = strategy.GetActivationExpression(scope, request); if (result != null) { break; } } return(result); }
/// <summary> /// Compiles an expression result to a delegate /// </summary> /// <param name="expressionContext"></param> /// <param name="parameters"></param> /// <param name="extraExpressions"></param> /// <param name="finalExpression"></param> /// <returns></returns> protected virtual ActivationStrategyDelegate CompileExpressionResultToDelegate( IActivationExpressionResult expressionContext, ParameterExpression[] parameters, Expression[] extraExpressions, Expression finalExpression) { Expression compileExpression; if (parameters.Length == 0 && extraExpressions.Length == 0) { compileExpression = finalExpression; } else { var list = new List <Expression>(expressionContext.ExtraExpressions()) { finalExpression }; compileExpression = Expression.Block(expressionContext.ExtraParameters(), list); } var compiled = Expression.Lambda <ActivationStrategyDelegate>(compileExpression, expressionContext.Request.Constants.ScopeParameter, expressionContext.Request.Constants.RootDisposalScope, expressionContext.Request.Constants.InjectionContextParameter).Compile(); return(compiled); }
/// <summary> /// try to create delegate using IL generation /// </summary> /// <param name="expressionContext">expression context</param> /// <param name="finalExpression">final expression to convert</param> /// <param name="newDelegate">created delegate</param> /// <returns>true if delegate was created</returns> public virtual bool TryCreateDelegate(IActivationExpressionResult expressionContext, Expression finalExpression, out ActivationStrategyDelegate newDelegate) { newDelegate = null; try { var request = new DynamicMethodGenerationRequest(expressionContext, TryGenerateIL); var constants = new List <object>(); if (!ImplementationFactory.Locate <IConstantExpressionCollector>().GetConstantExpressions(finalExpression, constants)) { return(false); } request.Constants = constants; var target = ImplementationFactory.Locate <IDynamicMethodTargetCreator>().CreateMethodTarget(request); if (target == null) { return(false); } request.Target = target; var method = new DynamicMethod(string.Empty, typeof(object), new[] { target.GetType(), typeof(IExportLocatorScope), typeof(IDisposalScope), typeof(IInjectionContext) }, target.GetType(), true); request.ILGenerator = method.GetILGenerator(); if (!TryGenerateIL(request, finalExpression)) { return(false); } request.ILGenerator.Emit(OpCodes.Ret); newDelegate = (ActivationStrategyDelegate)method.CreateDelegate(typeof(ActivationStrategyDelegate), target); return(true); } catch (Exception) { // ignore exception and compile linq expression normally } return(false); }
/// <summary> /// Replace values in expression /// </summary> /// <param name="expression"></param> /// <returns></returns> public IActivationExpressionResult Replace(Expression expression) { _result = _request.Services.Compiler.CreateNewResult(_request); _result.Expression = Visit(expression); return(_result); }
public T CompileOptimizedDelegate <T>(IInjectionScope scope, IActivationExpressionResult expressionContext) { ParameterExpression[] parameters; Expression[] extraExpressions; var finalExpression = ProcessExpressionResultForCompile(expressionContext, out parameters, out extraExpressions); var compiled = CompileExpressionResultToOpitimzed <T>(expressionContext, parameters, extraExpressions, finalExpression); return(compiled); }
//TODO: Typo in method name. protected virtual T CompileExpressionResultToOpitimzed <T>( IActivationExpressionResult expressionContext, ParameterExpression[] parameters, Expression[] extraExpressions, Expression finalExpression) { Expression compileExpression; if (parameters.Length == 0 && extraExpressions.Length == 0) { compileExpression = finalExpression; } else { var list = new List <Expression>(expressionContext.ExtraExpressions()) { finalExpression }; compileExpression = Expression.Block(expressionContext.ExtraParameters(), list); } var parameterList = new List <ParameterExpression>(); var invokeMethod = typeof(T).GetTypeInfo().GetDeclaredMethod("Invoke"); var parameterInfos = invokeMethod.GetParameters(); if (parameterInfos.Length > 3) { throw new Exception("Delegate type not supported: " + typeof(T).Name); } if (parameterInfos.Length > 0) { parameterList.Add(expressionContext.Request.Constants.ScopeParameter); } if (parameterInfos.Length > 1) { parameterList.Add(expressionContext.Request.Constants.RootDisposalScope); } if (parameterInfos.Length > 2) { parameterList.Add(expressionContext.Request.Constants.InjectionContextParameter); } var compiled = Expression.Lambda <T>(compileExpression, parameterList).Compile(); return(compiled); }
private static ParameterExpression CreateVariablExpression(TypeActivationConfiguration activationConfiguration, IActivationExpressionResult activationExpressionResult) { var variablExpression = Expression.Variable(activationConfiguration.ActivationType); activationExpressionResult.AddExtraParameter(variablExpression); activationExpressionResult.AddExtraExpression(Expression.Assign(variablExpression, activationExpressionResult.Expression)); activationExpressionResult.Expression = variablExpression; return(variablExpression); }
/// <summary> /// Create an array of expressions based off an array of types /// </summary> /// <param name="strategy"></param> /// <param name="scope"></param> /// <param name="request"></param> /// <param name="resultType"></param> /// <param name="types"></param> /// <returns></returns> public static IActivationExpressionResult[] CreateExpressionsForTypes(IActivationStrategy strategy, IInjectionScope scope, IActivationExpressionRequest request, Type resultType, params Type[] types) { var resultArray = new IActivationExpressionResult[types.Length]; for (var i = 0; i < types.Length; i++) { var arg1Request = request.NewRequest(types[i], strategy, resultType, RequestType.Other, null, true, true); resultArray[i] = request.Services.ExpressionBuilder.GetActivationExpression(scope, arg1Request); } return(resultArray); }
protected override T CompileExpressionResultToOpitimzed <T>(IActivationExpressionResult expressionContext, ParameterExpression[] parameters, Expression[] extraExpressions, Expression finalExpression) { T delegateValue = (T)(object)_linqToDynamicMethodConverter.TryCreateDelegate(expressionContext, parameters, extraExpressions, finalExpression, typeof(T)); if (delegateValue != null) { return(delegateValue); } expressionContext.Request.RequestingScope.ScopeConfiguration.Trace?.Invoke($"Could not generate delegate for {expressionContext.Request.ActivationType.FullName} using DynamicMethod falling back to linq expressions"); return(base.CompileExpressionResultToOpitimzed <T>(expressionContext, parameters, extraExpressions, finalExpression)); }
private void AddInjectionContextExpression(IActivationExpressionResult expressionContext) { var method = typeof(IInjectionContextCreator).GetRuntimeMethod("CreateContext", new[] { typeof(object) }); var newExpression = Expression.Call(Expression.Constant(_injectionContextCreator), method, Expression.Constant(null, typeof(object))); var assign = Expression.Assign(expressionContext.Request.InjectionContextParameter, newExpression); var ifThen = Expression.IfThen( Expression.Equal(expressionContext.Request.InjectionContextParameter, Expression.Constant(null, typeof(IInjectionContext))), assign); expressionContext.AddExtraExpression(ifThen, insertBeginning: true); }
/// <summary> /// Creates member injection statements /// </summary> /// <param name="scope"></param> /// <param name="request"></param> /// <param name="activationConfiguration"></param> /// <param name="result"></param> /// <returns></returns> protected virtual IActivationExpressionResult CreateMemberInjectExpressions(IInjectionScope scope, IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration, IActivationExpressionResult result) { var members = GetMemberInjectionInfoForConfiguration(scope, request, activationConfiguration); if (members.Count == 0) { return(result); } ParameterExpression variable = result.Expression as ParameterExpression; var newResult = request.Services.Compiler.CreateNewResult(request); if (variable == null) { variable = Expression.Variable(result.Expression.Type); newResult.AddExpressionResult(result); newResult.AddExtraParameter(variable); newResult.AddExtraExpression(Expression.Assign(variable, result.Expression)); } foreach (var memberKVP in members) { var expression = memberKVP.Value.CreateExpression; if (expression == null) { var memberType = memberKVP.Key.GetMemeberType(); var newRequest = request.NewRequest(memberType, activationConfiguration.ActivationStrategy, activationConfiguration.ActivationType, RequestType.Member, memberKVP.Key, false, true); if (memberKVP.Value.LocateKey == null && scope.ScopeConfiguration.Behaviors.KeyedTypeSelector(memberType)) { newRequest.SetLocateKey(memberKVP.Key.Name); } else { newRequest.SetLocateKey(memberKVP.Value.LocateKey); } newRequest.IsDynamic = memberKVP.Value.IsDynamic; newRequest.SetIsRequired(memberKVP.Value.IsRequired); newRequest.SetFilter(memberKVP.Value.Filter); if (memberKVP.Value.DefaultValue != null) { newRequest.SetDefaultValue( new DefaultValueInformation { DefaultValue = memberKVP.Value.DefaultValue }); } var memberResult = request.Services.ExpressionBuilder.GetActivationExpression(scope, newRequest); if (memberResult == null) { if (memberKVP.Value.IsRequired) { throw new LocateException(newRequest.GetStaticInjectionContext()); } } else { Expression memberExpression; if (memberKVP.Key is FieldInfo) { memberExpression = Expression.Field(variable, memberKVP.Key as FieldInfo); } else if (memberKVP.Key is PropertyInfo) { memberExpression = Expression.Property(variable, (PropertyInfo)memberKVP.Key); } else { throw new LocateException(request.GetStaticInjectionContext(), $"{memberKVP.Key.GetType().Name} member type not supported"); } newResult.AddExpressionResult(memberResult); newResult.AddExtraExpression(Expression.Assign(memberExpression, memberResult.Expression)); } } else { Expression memberExpression; if (memberKVP.Key is FieldInfo) { memberExpression = Expression.Field(variable, memberKVP.Key as FieldInfo); } else if (memberKVP.Key is PropertyInfo) { memberExpression = Expression.Property(variable, (PropertyInfo)memberKVP.Key); } else { throw new LocateException(request.GetStaticInjectionContext(), $"{memberKVP.Key.GetType().Name} member type not supported"); } newResult.AddExtraExpression(Expression.Assign(memberExpression, expression)); } } newResult.Expression = variable; return(newResult); }
/// <summary> /// Create enrichment expressions /// </summary> /// <param name="scope">scope for strategy</param> /// <param name="request">request</param> /// <param name="activationConfiguration">activation configuration</param> /// <param name="result">expression result</param> /// <returns></returns> public IActivationExpressionResult CreateExpression(IInjectionScope scope, IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration, IActivationExpressionResult result) { var expression = result.Expression; foreach (var enrichmentDelegate in activationConfiguration.EnrichmentDelegates.Reverse()) { var invokeMethod = enrichmentDelegate.GetType().GetRuntimeMethods().First(m => m.Name == "Invoke"); var expressions = new List <Expression>(); foreach (var parameter in invokeMethod.GetParameters()) { if (parameter.ParameterType == expression.Type) { expressions.Add(expression); } else { var arg1Request = request.NewRequest(parameter.ParameterType, activationConfiguration.ActivationStrategy, expression.Type, RequestType.Other, null, true, true); var activationExpression = request.Services.ExpressionBuilder.GetActivationExpression(scope, arg1Request); result.AddExpressionResult(activationExpression); expressions.Add(activationExpression.Expression); } } expression = Expression.Call(Expression.Constant(enrichmentDelegate), invokeMethod, expressions); } result.Expression = expression; return(result); }
public IActivationExpressionResult CreateExpression(IInjectionScope scope, IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration, IActivationExpressionResult result) { var closedActionType = typeof(Action <>).MakeGenericType(activationConfiguration.ActivationType); object disposalDelegate = null; if (closedActionType == activationConfiguration.DisposalDelegate?.GetType()) { disposalDelegate = activationConfiguration.DisposalDelegate; } MethodInfo closedGeneric; Expression[] parameterExpressions; var resultExpression = result.Expression; if (resultExpression.Type != activationConfiguration.ActivationType) { resultExpression = Expression.Convert(resultExpression, activationConfiguration.ActivationType); } if (disposalDelegate != null) { closedGeneric = AddMethodWithCleanup.MakeGenericMethod(activationConfiguration.ActivationType); parameterExpressions = new[] { request.DisposalScopeExpression, resultExpression, Expression.Convert(Expression.Constant(disposalDelegate), closedActionType) }; } else { closedGeneric = AddMethod.MakeGenericMethod(activationConfiguration.ActivationType); parameterExpressions = new[] { request.DisposalScopeExpression, resultExpression }; } var disposalCall = Expression.Call(closedGeneric, parameterExpressions); var disposalResult = request.Services.Compiler.CreateNewResult(request, disposalCall); disposalResult.AddExpressionResult(result); return(disposalResult); }
private static Delegate CompileFuncDelage <T>(IActivationExpressionRequest request, IInjectionScope scope, IActivationExpressionResult result) { return(request.Services.Compiler.CompileOptimizedDelegate <Func <T> >(scope, result)); }
private IActivationExpressionResult CreateTimedCreateExpression(IInjectionScope scope, IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration, IActivationExpressionResult expression) { var result = request.Services.Compiler.CreateNewResult(request); var returnVar = Expression.Variable(typeof(object)); var staticContext = request.GetStaticInjectionContext(); var callExpression = Expression.Call(Expression.Constant(this), PreBuildUpMethodInfo, Expression.Constant(staticContext), request.Constants.ScopeParameter, request.InjectionContextParameter); result.AddExtraParameter(returnVar); result.AddExtraExpression(Expression.Assign(returnVar, callExpression)); result.AddExtraExpression( Expression.IfThen(Expression.Equal(returnVar, Expression.Constant(null, typeof(object))), Expression.Assign(returnVar, expression.Expression))); result.Expression = Expression.Call(Expression.Constant(this), PostBuildUpMethodInfo, returnVar, Expression.Constant(staticContext), request.ScopeParameter, request.InjectionContextParameter); return(result); }
/// <summary> /// Create expressions for calling methods /// </summary> /// <param name="scope">scope for strategy</param> /// <param name="request">request</param> /// <param name="activationConfiguration">configuration information</param> /// <param name="activationExpressionResult">expression result</param> /// <returns>expression result</returns> public IActivationExpressionResult CreateExpression(IInjectionScope scope, IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration, IActivationExpressionResult activationExpressionResult) { ParameterExpression variableExpression = null; foreach (var selector in activationConfiguration.MemberInjectionSelectors) { foreach (var methodInjectionInfo in selector.GetMethods(activationConfiguration.ActivationType, request.RequestingScope, request)) { if (variableExpression == null) { variableExpression = CreateVariablExpression(activationConfiguration, activationExpressionResult); } AddMethodCall(scope, request, activationConfiguration, activationExpressionResult, methodInjectionInfo, variableExpression); } } foreach (var methodInjectionInfo in activationConfiguration.MethodInjections) { if (variableExpression == null) { variableExpression = CreateVariablExpression(activationConfiguration, activationExpressionResult); } AddMethodCall(scope, request, activationConfiguration, activationExpressionResult, methodInjectionInfo, variableExpression); } if (activationConfiguration.ActivationMethod != null) { if (variableExpression == null) { variableExpression = CreateVariablExpression(activationConfiguration, activationExpressionResult); } AddMethodCall(scope, request, activationConfiguration, activationExpressionResult, activationConfiguration.ActivationMethod, variableExpression); } return(activationExpressionResult); }
/// <summary> /// Default constructor /// </summary> /// <param name="expressionResult"></param> public DynamicMethodGenerationRequest(IActivationExpressionResult expressionResult, Func <DynamicMethodGenerationRequest, Expression, bool> tryGenerateIL) { ExpressionResult = expressionResult; TryGenerateIL = tryGenerateIL; ExpressionRequest = ExpressionResult.Request; }
/// <summary> /// try to create delegate using IL generation /// </summary> /// <param name="expressionContext">expression context</param> /// <param name="parameters"></param> /// <param name="extraExpressions"></param> /// <param name="finalExpression">final expression to convert</param> /// <param name="newDelegate">created delegate</param> /// <returns>true if delegate was created</returns> public virtual bool TryCreateDelegate(IActivationExpressionResult expressionContext, ParameterExpression[] parameters, Expression[] extraExpressions, Expression finalExpression, out ActivationStrategyDelegate newDelegate) { newDelegate = null; try { var request = new DynamicMethodGenerationRequest(expressionContext, TryGenerateIL, parameters); var constants = new List <object>(); foreach (var expression in extraExpressions) { if (!ImplementationFactory.Locate <IConstantExpressionCollector>().GetConstantExpressions(expression, constants)) { return(false); } } if (!ImplementationFactory.Locate <IConstantExpressionCollector>().GetConstantExpressions(finalExpression, constants)) { return(false); } request.Constants = constants; var target = ImplementationFactory.Locate <IDynamicMethodTargetCreator>().CreateMethodTarget(request); if (target == null) { return(false); } request.Target = target; var method = new DynamicMethod(string.Empty, typeof(object), new[] { target.GetType(), typeof(IExportLocatorScope), typeof(IDisposalScope), typeof(IInjectionContext) }, target.GetType(), true); request.ILGenerator = method.GetILGenerator(); foreach (var parameter in parameters) { request.ILGenerator.DeclareLocal(parameter.Type); } foreach (var expression in extraExpressions) { if (!TryGenerateIL(request, expression)) { return(false); } } if (!TryGenerateIL(request, finalExpression)) { return(false); } request.ILGenerator.Emit(OpCodes.Ret); newDelegate = (ActivationStrategyDelegate)method.CreateDelegate(typeof(ActivationStrategyDelegate), target); return(true); } catch (Exception exp) { expressionContext.Request.RequestingScope.ScopeConfiguration.Trace?.Invoke($"Exception thrown while compiling dynamic method {exp.Message}"); } return(false); }
/// <summary> /// Allow constructor selector to override method /// </summary> /// <param name="injectionScope"></param> /// <param name="configuration"></param> /// <param name="request"></param> /// <param name="constructor"></param> /// <param name="expression"></param> /// <returns></returns> protected virtual IActivationExpressionResult OverrideExpression(IInjectionScope injectionScope, TypeActivationConfiguration configuration, IActivationExpressionRequest request, ConstructorInfo constructor, IActivationExpressionResult expression) { return(expression); }
/// <summary> /// Compile a delegate /// </summary> /// <param name="scope"></param> /// <param name="expressionContext"></param> /// <returns></returns> public virtual ActivationStrategyDelegate CompileDelegate(IInjectionScope scope, IActivationExpressionResult expressionContext) { ParameterExpression[] parameters; Expression[] extraExpressions; var finalExpression = ProcessExpressionResultForCompile(expressionContext, out parameters, out extraExpressions); var compiled = CompileExpressionResultToDelegate(expressionContext, parameters, extraExpressions, finalExpression); return(compiled); }
/// <summary> /// Compiles an expression result to a delegate /// </summary> /// <param name="expressionContext"></param> /// <param name="parameters"></param> /// <param name="extraExpressions"></param> /// <param name="finalExpression"></param> /// <returns></returns> protected override ActivationStrategyDelegate CompileExpressionResultToDelegate(IActivationExpressionResult expressionContext, ParameterExpression[] parameters, Expression[] extraExpressions, Expression finalExpression) { ActivationStrategyDelegate dynamicDelegate; // try to create delegate, if not fall back to normal Linq Expression compile if (_linqToDynamicMethodConverter.TryCreateDelegate(expressionContext, parameters, extraExpressions, finalExpression, out dynamicDelegate)) { return(dynamicDelegate); } expressionContext.Request.RequestingScope.ScopeConfiguration.Trace?.Invoke($"Could not generate delegate for {expressionContext.Request.ActivationType.FullName} using DynamicMethod falling back to linq expressions"); return(base.CompileExpressionResultToDelegate(expressionContext, parameters, extraExpressions, finalExpression)); }
/// <summary> /// Create member initialization statement if needed /// </summary> /// <param name="scope">scope for strategy</param> /// <param name="request">expression request</param> /// <param name="activationConfiguration">activation configuration</param> /// <param name="result">initialization expression</param> /// <returns></returns> public IActivationExpressionResult CreateExpression(IInjectionScope scope, IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration, IActivationExpressionResult result) { var expression = result.Expression as NewExpression; if (expression != null) { return(CreateNewMemeberInitExpression(scope, request, activationConfiguration, result, expression)); } throw new NotSupportedException("Currently only memeber injection works for New expressions"); }
/// <summary> /// Compiles an expression result to a delegate /// </summary> /// <param name="expressionContext"></param> /// <param name="parameters"></param> /// <param name="extraExpressions"></param> /// <param name="finalExpression"></param> /// <returns></returns> protected override ActivationStrategyDelegate CompileExpressionResultToDelegate(IActivationExpressionResult expressionContext, ParameterExpression[] parameters, Expression[] extraExpressions, Expression finalExpression) { if (parameters.Length == 0 && extraExpressions.Length == 0) { ActivationStrategyDelegate dynamicDelegate; // try to create delegate, if not fall back to normal Linq Expression compile if (_linqToDynamicMethodConverter.TryCreateDelegate(expressionContext, finalExpression, out dynamicDelegate)) { return(dynamicDelegate); } } return(base.CompileExpressionResultToDelegate(expressionContext, parameters, extraExpressions, finalExpression)); }
/// <summary> /// Create member init expression /// </summary> /// <param name="scope">scope for configuration</param> /// <param name="request">request</param> /// <param name="activationConfiguration">activation configuration</param> /// <param name="result">result from instantation</param> /// <param name="newExpression">instantiation expression</param> /// <returns></returns> protected virtual IActivationExpressionResult CreateNewMemeberInitExpression(IInjectionScope scope, IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration, IActivationExpressionResult result, NewExpression newExpression) { var bindings = new List <MemberBinding>(); var members = GetMemberInjectionInfoForConfiguration(scope, request, activationConfiguration); foreach (var memberKVP in members) { var expression = memberKVP.Value.CreateExpression; if (expression == null) { var memberType = memberKVP.Key.GetMemeberType(); var newRequest = request.NewRequest(memberType, activationConfiguration.ActivationStrategy, activationConfiguration.ActivationType, RequestType.Member, memberKVP.Key, false, true); if (memberKVP.Value.LocateKey == null && scope.ScopeConfiguration.Behaviors.KeyedTypeSelector(memberType)) { newRequest.SetLocateKey(memberKVP.Key.Name); } else { newRequest.SetLocateKey(memberKVP.Value.LocateKey); } newRequest.IsDynamic = memberKVP.Value.IsDynamic; newRequest.SetIsRequired(memberKVP.Value.IsRequired); newRequest.SetFilter(memberKVP.Value.Filter); if (memberKVP.Value.DefaultValue != null) { newRequest.SetDefaultValue(new DefaultValueInformation { DefaultValue = memberKVP.Value.DefaultValue }); } var memberResult = request.Services.ExpressionBuilder.GetActivationExpression(scope, newRequest); if (memberResult == null) { if (memberKVP.Value.IsRequired) { throw new LocateException(newRequest.GetStaticInjectionContext()); } } else { bindings.Add(Expression.Bind(memberKVP.Key, memberResult.Expression)); result.AddExpressionResult(memberResult); } } else { bindings.Add(Expression.Bind(memberKVP.Key, expression)); } } if (bindings.Count > 0) { result.Expression = Expression.MemberInit(newExpression, bindings); } return(result); }
/// <summary> /// Create member initialization statement if needed /// </summary> /// <param name="scope">scope for strategy</param> /// <param name="request">expression request</param> /// <param name="activationConfiguration">activation configuration</param> /// <param name="result">initialization expression</param> /// <returns></returns> public IActivationExpressionResult CreateExpression(IInjectionScope scope, IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration, IActivationExpressionResult result) { var expression = result.Expression as NewExpression; if (expression != null) { return(CreateNewMemeberInitExpression(scope, request, activationConfiguration, result, expression)); } return(CreateMemberInjectExpressions(scope, request, activationConfiguration, result)); }
/// <summary> /// Create expression to add instance to disposal scope /// </summary> /// <param name="scope">scope for strategy</param> /// <param name="request">request</param> /// <param name="activationConfiguration">activation configuration</param> /// <param name="result">result for instantiation</param> /// <returns></returns> public IActivationExpressionResult CreateExpression(IInjectionScope scope, IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration, IActivationExpressionResult result) { var closedGeneric = AddMethod.MakeGenericMethod(activationConfiguration.ActivationType); var closedActionType = typeof(Action <>).MakeGenericType(activationConfiguration.ActivationType); object disposalDelegate = null; if (closedActionType == activationConfiguration.DisposalDelegate?.GetType()) { disposalDelegate = activationConfiguration.DisposalDelegate; } var disposalCall = Expression.Call(request.DisposalScopeExpression, closedGeneric, result.Expression, Expression.Convert(Expression.Constant(disposalDelegate), closedActionType)); var disposalResult = request.Services.Compiler.CreateNewResult(request, disposalCall); disposalResult.AddExpressionResult(result); return(disposalResult); }
/// <summary> /// Add child expression result /// </summary> /// <param name="result">expression result</param> public void AddExpressionResult(IActivationExpressionResult result) { _extraExpressions = _extraExpressions.AddRange(result.ExtraExpressions()); _parameterExpressions = _parameterExpressions.AddRange(result.ExtraParameters()); }
private static void AddMethodCall(IInjectionScope scope, IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration, IActivationExpressionResult activationExpressionResult, MethodInjectionInfo methodInjectionInfo, ParameterExpression variableExpression) { var parameterResults = new List <IActivationExpressionResult>(); foreach (var parameter in methodInjectionInfo.Method.GetParameters()) { var parameterRequest = request.NewRequest(parameter.ParameterType, activationConfiguration.ActivationStrategy, activationConfiguration.ActivationType, RequestType.MethodParameter, parameter, false, true); if (scope.ScopeConfiguration.Behaviors.KeyedTypeSelector(parameter.ParameterType)) { parameterRequest.SetLocateKey(parameter.Name); } var parameterInfo = methodInjectionInfo.ParameterInfos() .Where(p => p.ParameterName == parameter.Name) .FirstOrDefault(); if (parameterInfo != null) { parameterRequest.SetIsRequired(parameterInfo.IsRequired); parameterRequest.SetLocateKey(parameterInfo.LocateKey); } var result = request.Services.ExpressionBuilder.GetActivationExpression(scope, parameterRequest); parameterResults.Add(result); activationExpressionResult.AddExpressionResult(result); } activationExpressionResult.AddExtraExpression(Expression.Call(variableExpression, methodInjectionInfo.Method, parameterResults.Select(r => r.Expression))); }