/// <summary>Visits the children of the <see cref="T:System.Linq.Expressions.MethodCallExpression" />.</summary> /// <returns>The modified expression, if it or any subexpression was modified; otherwise, returns the original expression.</returns> /// <param name="node">The expression to visit.</param> protected override Expression VisitMethodCall(MethodCallExpression node) { if (node.Method.DeclaringType == typeof(Arg)) { var methodName = node.Method.Name; if (methodName == nameof(Arg.Any) || methodName == nameof(Arg.Locate)) { var newRequest = _request.NewRequest(node.Method.GetGenericArguments().First(), _activationStrategy, _activationStrategy.ActivationType, RequestType.Other, null, true, true); var arguement = node.Arguments.FirstOrDefault(); if (arguement != null) { var replaceNode = (MethodCallExpression)base.VisitMethodCall(node); arguement = replaceNode.Arguments.First(); if (arguement is NewExpression newExpression) { var parameters = newExpression.Constructor.GetParameters(); for (int i = 0; i < parameters.Length; i++) { var expression = newExpression.Arguments[i]; var parameter = parameters[i]; var knownValue = new SimpleKnownValueExpression(expression.Type, expression, parameter.Name); newRequest.AddKnownValueExpression(knownValue); } } } var activationExpression = _request.Services.ExpressionBuilder.GetActivationExpression(_request.RequestingScope, newRequest); _result.AddExpressionResult(activationExpression); return(activationExpression.Expression); } if (methodName == nameof(Arg.Scope)) { _request.RequireExportScope(); return(_request.ScopeParameter); } if (methodName == nameof(Arg.Context)) { return(_request.InjectionContextParameter); } } return(base.VisitMethodCall(node)); }
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 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))); }
/// <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.GetTypeInfo().IsAssignableFrom(expression.Type.GetTypeInfo())) { 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); if (activationConfiguration.ActivationType != expression.Type) { expression = Expression.Convert(expression, activationConfiguration.ActivationType); } } result.Expression = expression; return(result); }
/// <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); }