/// <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>
        /// 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);
        }
Пример #3
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="newDelegateType">created delegate</param>
        /// <returns>true if delegate was created</returns>
        public virtual Delegate TryCreateDelegate(IActivationExpressionResult expressionContext, ParameterExpression[] parameters, Expression[] extraExpressions, Expression finalExpression, Type newDelegateType)
        {
            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(null);
                    }
                }

                if (!ImplementationFactory.Locate <IConstantExpressionCollector>().GetConstantExpressions(finalExpression, constants))
                {
                    return(null);
                }

                request.Constants = constants;

                var target = ImplementationFactory.Locate <IDynamicMethodTargetCreator>().CreateMethodTarget(request);

                request.Target = target;

                var invokeMethod = newDelegateType.GetTypeInfo().GetDeclaredMethod("Invoke");

                var parameterTypes = new List <Type>();

                if (target != null)
                {
                    parameterTypes.Add(target.GetType());
                }

                parameterTypes.AddRange(invokeMethod.GetParameters().Select(p => p.ParameterType));

                var method = new DynamicMethod(string.Empty,
                                               invokeMethod.ReturnType,
                                               parameterTypes.ToArray(),
                                               typeof(LinqToDynamicMethodConverter),
                                               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(null);
                    }
                }

                if (!TryGenerateIL(request, finalExpression))
                {
                    return(null);
                }

                request.ILGenerator.Emit(OpCodes.Ret);

                return(method.CreateDelegate(newDelegateType, target));
            }
            catch (Exception exp)
            {
                expressionContext.Request.RequestingScope.ScopeConfiguration.Trace?.Invoke($"Exception thrown while compiling dynamic method {exp.Message}");
            }

            return(null);
        }