示例#1
0
        /// <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));
        }
示例#2
0
        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);
        }
示例#4
0
        /// <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);
        }