コード例 #1
0
        /// <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);
        }
コード例 #2
0
 /// <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;
 }
コード例 #3
0
        /// <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);
        }
コード例 #4
0
        /// <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);
        }
コード例 #5
0
        /// <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);
        }
コード例 #6
0
        /// <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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        //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);
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        /// <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);
        }
コード例 #11
0
        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));
        }
コード例 #12
0
        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);
        }
コード例 #13
0
        /// <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);
        }
コード例 #14
0
        /// <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);
        }
コード例 #15
0
        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);
        }
コード例 #16
0
 private static Delegate CompileFuncDelage <T>(IActivationExpressionRequest request, IInjectionScope scope,
                                               IActivationExpressionResult result)
 {
     return(request.Services.Compiler.CompileOptimizedDelegate <Func <T> >(scope, result));
 }
コード例 #17
0
        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);
        }
コード例 #18
0
        /// <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);
        }
コード例 #19
0
 /// <summary>
 /// Default constructor
 /// </summary>
 /// <param name="expressionResult"></param>
 public DynamicMethodGenerationRequest(IActivationExpressionResult expressionResult, Func <DynamicMethodGenerationRequest, Expression, bool> tryGenerateIL)
 {
     ExpressionResult  = expressionResult;
     TryGenerateIL     = tryGenerateIL;
     ExpressionRequest = ExpressionResult.Request;
 }
コード例 #20
0
        /// <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);
        }
コード例 #21
0
 /// <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);
 }
コード例 #22
0
        /// <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);
        }
コード例 #23
0
        /// <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));
        }
コード例 #24
0
        /// <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");
        }
コード例 #25
0
        /// <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));
        }
コード例 #26
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);
        }
コード例 #27
0
        /// <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));
        }
コード例 #28
0
        /// <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);
        }
コード例 #29
0
 /// <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());
 }
コード例 #30
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 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)));
        }