Пример #1
0
 /// <summary>
 /// Test if the parameter was specified
 /// </summary>
 /// <param name="configuration"></param>
 /// <param name="parameter"></param>
 /// <returns></returns>
 protected virtual bool CanGetValueFromInfo(TypeActivationConfiguration configuration, ParameterInfo parameter)
 {
     return(false);
 }
 /// <summary>
 /// Create call expression for delegate
 /// </summary>
 /// <param name="scope"></param>
 /// <param name="request"></param>
 /// <param name="activationConfiguration"></param>
 /// <param name="activationDelegate"></param>
 /// <returns></returns>
 protected virtual IActivationExpressionResult CreateCallExpression(IInjectionScope scope, IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration, ActivationStrategyDelegate activationDelegate)
 {
     return(ExpressionUtilities.CreateExpressionForDelegate(activationDelegate, activationConfiguration.ExternallyOwned,
                                                            scope, request));
 }
Пример #3
0
        /// <summary>
        /// Get a list of dependencies for a constructor
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="request"></param>
        /// <param name="constructor"></param>
        /// <returns></returns>
        protected virtual IEnumerable <ActivationStrategyDependency> GetDependenciesForConstructor(TypeActivationConfiguration configuration, IActivationExpressionRequest request, ConstructorInfo constructor)
        {
            var dependencies   = ImmutableLinkedList <ActivationStrategyDependency> .Empty;
            var injectionScope = request.RequestingScope;

            foreach (var parameter in constructor.GetParameters())
            {
                object key = null;

                if (injectionScope.ScopeConfiguration.Behaviors.KeyedTypeSelector(parameter.ParameterType))
                {
                    key = parameter.Name;
                }

                var dependencySatisified = parameter.IsOptional ||
                                           parameter.ParameterType.IsGenericParameter ||
                                           CanGetValueFromInfo(configuration, parameter) ||
                                           injectionScope.CanLocate(parameter.ParameterType, null, key);

                var dependency = new ActivationStrategyDependency(DependencyType.ConstructorParameter,
                                                                  configuration.ActivationStrategy,
                                                                  parameter,
                                                                  parameter.ParameterType,
                                                                  parameter.Name,
                                                                  false,
                                                                  false,
                                                                  dependencySatisified);

                dependencies = dependencies.Add(dependency);
            }

            return(dependencies);
        }
        /// <summary>
        /// Get activation expression for type configuration
        /// </summary>
        /// <param name="scope">scope</param>
        /// <param name="request">request</param>
        /// <param name="activationConfiguration">activation configuration</param>
        /// <param name="lifestyle">lifestyle</param>
        /// <returns></returns>
        public IActivationExpressionResult GetActivationExpression(IInjectionScope scope, IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration, ICompiledLifestyle lifestyle)
        {
            if (lifestyle == null)
            {
                return(TypeExpressionBuilder.GetActivationExpression(scope, request, activationConfiguration));
            }

            return(lifestyle.ProvideLifestyleExpression(scope, request,
                                                        lifestyleRequest => TypeExpressionBuilder.GetActivationExpression(scope, lifestyleRequest, activationConfiguration)));
        }
Пример #5
0
        /// <summary>
        /// Get expression for parameter
        /// </summary>
        /// <param name="parameter"></param>
        /// <param name="parameterInfo"></param>
        /// <param name="injectionScope"></param>
        /// <param name="configuration"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        protected virtual IActivationExpressionResult GetParameterExpression(ParameterInfo parameter, ConstructorParameterInfo parameterInfo, IInjectionScope injectionScope, TypeActivationConfiguration configuration, IActivationExpressionRequest request, out IActivationExpressionRequest newRequest)
        {
            if (parameterInfo?.ExportFunc != null)
            {
                newRequest = null;

                return(CallExportFunc(configuration.ActivationStrategy, parameter, parameterInfo, injectionScope, request, configuration.ExternallyOwned));
            }

            newRequest = request.NewRequest(parameterInfo?.UseType ?? parameter.ParameterType,
                                            configuration.ActivationStrategy,
                                            configuration.ActivationType,
                                            RequestType.ConstructorParameter,
                                            parameter,
                                            true,
                                            true);

            if (parameterInfo?.LocateWithKey != null)
            {
                newRequest.SetLocateKey(parameterInfo.LocateWithKey);
            }
            else if (injectionScope.ScopeConfiguration.Behaviors.KeyedTypeSelector(parameter.ParameterType))
            {
                newRequest.SetLocateKey(parameter.Name);
            }

            if (parameterInfo?.DefaultValue != null)
            {
                newRequest.SetDefaultValue(new DefaultValueInformation {
                    DefaultValue = parameterInfo.DefaultValue
                });
            }
            else if (parameter.HasDefaultValue)
            {
                newRequest.SetDefaultValue(new DefaultValueInformation {
                    DefaultValue = parameter.DefaultValue
                });
            }

            if (parameterInfo != null)
            {
                newRequest.IsDynamic = parameterInfo.IsDynamic;

                newRequest.SetIsRequired(parameterInfo.IsRequired.GetValueOrDefault(!parameter.IsOptional));

                newRequest.SetFilter(parameterInfo.ExportStrategyFilter);

                newRequest.SetEnumerableComparer(parameterInfo.EnumerableComparer);
            }
            else
            {
                newRequest.SetIsRequired(!parameter.IsOptional);
            }

            return(newRequest.Services.ExpressionBuilder.GetActivationExpression(injectionScope, newRequest));
        }
Пример #6
0
 /// <summary>
 /// This method is called when there are multiple constructors
 /// </summary>
 /// <param name="injectionScope"></param>
 /// <param name="configuration"></param>
 /// <param name="request"></param>
 /// <param name="constructors"></param>
 /// <returns></returns>
 protected abstract ConstructorInfo PickConstructor(IInjectionScope injectionScope,
                                                    TypeActivationConfiguration configuration, IActivationExpressionRequest request, ConstructorInfo[] constructors);
        /// <summary>
        /// This method is called when there are multiple constructors
        /// </summary>
        /// <param name="injectionScope"></param>
        /// <param name="configuration"></param>
        /// <param name="request"></param>
        /// <param name="constructors"></param>
        /// <returns></returns>
        protected override ConstructorInfo PickConstructor(IInjectionScope injectionScope, TypeActivationConfiguration configuration,
                                                           IActivationExpressionRequest request, ConstructorInfo[] constructors)
        {
            ConstructorInfo returnConstructor = null;
            var             matchInfos        = new List <MatchInfo>();

            foreach (var constructor in constructors)
            {
                var matchInfo = new MatchInfo {
                    ConstructorInfo = constructor
                };

                foreach (var parameter in constructor.GetParameters())
                {
                    object key = null;

                    if (injectionScope.ScopeConfiguration.Behaviors.KeyedTypeSelector(parameter.ParameterType))
                    {
                        key = parameter.Name;
                    }

                    if (parameter.IsOptional ||
                        parameter.ParameterType.IsGenericParameter ||
                        CanGetValueFromInfo(configuration, parameter) ||
                        CanGetValueFromKnownValues(request, parameter) ||
                        injectionScope.CanLocate(parameter.ParameterType, null, key))
                    {
                        matchInfo.Matched++;
                    }
                    else
                    {
                        matchInfo.Missing++;
                    }
                }

                if (matchInfo.Missing == 0)
                {
                    returnConstructor = constructor;
                    break;
                }

                matchInfos.Add(matchInfo);
            }

            if (returnConstructor == null)
            {
                var comparer = Comparer <int> .Default;

                matchInfos.Sort((x, y) => comparer.Compare(x.Matched - x.Missing, y.Matched - y.Missing));

                returnConstructor = matchInfos.Last().ConstructorInfo;
            }

            return(returnConstructor);
        }
Пример #8
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);
 }
        /// <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.GetMemberType();

                    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 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));
        }
Пример #11
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);
        }
Пример #12
0
        private IEnumerable <ActivationStrategyDependency> GetDependenciesForMethod(MethodInjectionInfo methodInjection, TypeActivationConfiguration configuration, IActivationExpressionRequest request)
        {
            var list = ImmutableLinkedList <ActivationStrategyDependency> .Empty;

            foreach (var parameter in methodInjection.Method.GetParameters())
            {
                object key = null;

                if (request.RequestingScope.ScopeConfiguration.Behaviors.KeyedTypeSelector(parameter.ParameterType))
                {
                    key = parameter.Name;
                }

                var found = parameter.ParameterType.IsGenericParameter ||
                            request.RequestingScope.CanLocate(parameter.ParameterType, key: key);

                list =
                    list.Add(new ActivationStrategyDependency(DependencyType.MethodParameter,
                                                              configuration.ActivationStrategy,
                                                              parameter,
                                                              parameter.ParameterType,
                                                              parameter.Name,
                                                              false,
                                                              false,
                                                              found));
            }

            return(list);
        }
        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>
        /// Given an expression create an activation delegate
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="request"></param>
        /// <param name="activationConfiguration"></param>
        /// <returns></returns>
        protected virtual ActivationStrategyDelegate CreateActivationDelegate(IInjectionScope scope, IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration)
        {
            var activationExpression = BuildActivationExpression(scope, request, activationConfiguration);

            return(request.Services.Compiler.CompileDelegate(scope, activationExpression));
        }
Пример #15
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);

                    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);
        }
        private IActivationExpressionResult BuildActivationExpression(IInjectionScope scope, IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration)
        {
            var returnLabel             = Expression.Label(typeof(object));
            var variables               = new List <ParameterExpression>();
            var testVariableExpressions = new List <Expression>();
            var testExpressions         = new List <Expression>();

            var foundValues = new Dictionary <string, Tuple <ParameterExpression, string> >();
            var throwAtEnd  = true;

            foreach (var constructorInfo in GetConstructors(activationConfiguration.ActivationType))
            {
                var testParameters   = new List <ParameterExpression>();
                var locateParameters = new List <Expression>();

                foreach (var parameter in constructorInfo.GetParameters())
                {
                    var paramKey = parameter.Name + "|" + parameter.ParameterType.FullName;

                    Tuple <ParameterExpression, string> parameterExpression;

                    if (!foundValues.TryGetValue(paramKey, out parameterExpression))
                    {
                        var canLocateInfo = CreateCanLocateStatement(parameter, scope, request, activationConfiguration);

                        // only test for required parameters with no default value
                        if (canLocateInfo != null)
                        {
                            parameterExpression = new Tuple <ParameterExpression, string>(canLocateInfo.Item1, $"{parameter.ParameterType.Name} {parameter.Name}");

                            foundValues.Add(paramKey, parameterExpression);
                            variables.Add(parameterExpression.Item1);
                            testVariableExpressions.Add(canLocateInfo.Item2);
                        }
                    }

                    if (parameterExpression != null)
                    {
                        testParameters.Add(parameterExpression.Item1);
                    }

                    locateParameters.Add(CreateLocateExpression(parameter, scope, request, activationConfiguration));
                }

                var newValue = Expression.Return(returnLabel, Expression.New(constructorInfo, locateParameters));

                if (testParameters.Count > 0)
                {
                    if (testParameters.Count == 1)
                    {
                        testExpressions.Add(Expression.IfThen(Expression.IsTrue(testParameters[0]), newValue));
                    }
                    else
                    {
                        var andExpression = Expression.And(testParameters[0], testParameters[1]);

                        for (int i = 2; i < testParameters.Count; i++)
                        {
                            andExpression = Expression.And(andExpression, testParameters[i]);
                        }

                        testExpressions.Add(Expression.IfThen(andExpression, newValue));
                    }
                }
                else
                {
                    testExpressions.Add(newValue);
                    throwAtEnd = false;
                    break;
                }
            }

            if (throwAtEnd)
            {
                var constructor = typeof(LocateException).GetTypeInfo()
                                  .DeclaredConstructors.Single(c => c.GetParameters().Length == 2);

                var testValues = foundValues.Values.ToArray();

                var foundArrayExpression = Expression.NewArrayInit(typeof(bool), testValues.Select(t => t.Item1));
                var labelArray           = Expression.Constant(testValues.Select(t => t.Item2).ToArray());

                var createErrorStringMethod = typeof(DynamicConstructorExpressionCreator).GetTypeInfo()
                                              .GetDeclaredMethod("CreateMissingErrorMessage");

                testExpressions.Add(Expression.Throw(Expression.New(constructor,
                                                                    Expression.Constant(request.GetStaticInjectionContext()),
                                                                    Expression.Call(createErrorStringMethod, foundArrayExpression, labelArray))));
            }

            var result =
                request.Services.Compiler.CreateNewResult(request, Expression.Label(returnLabel, Expression.Default(request.ActivationType)));

            foreach (var variable in variables)
            {
                result.AddExtraParameter(variable);
            }

            foreach (var expression in testVariableExpressions)
            {
                result.AddExtraExpression(expression);
            }

            foreach (var expression in testExpressions)
            {
                result.AddExtraExpression(expression);
            }

            return(result);
        }
Пример #17
0
        /// <summary>
        /// Get dictionary of members that need to be injected
        /// </summary>
        /// <param name="scope">scope</param>
        /// <param name="request">expression request</param>
        /// <param name="activationConfiguration">activation configuration</param>
        /// <returns></returns>
        protected virtual Dictionary <MemberInfo, MemberInjectionInfo> GetMemberInjectionInfoForConfiguration(IInjectionScope scope,
                                                                                                              IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration)
        {
            var members = new Dictionary <MemberInfo, MemberInjectionInfo>();

            var currentScope = scope;

            while (currentScope != null)
            {
                ProcessMemberSelectors(scope, request, activationConfiguration.ActivationType, currentScope.MemberInjectionSelectors, members);

                currentScope = currentScope.Parent as IInjectionScope;
            }

            ProcessMemberSelectors(scope, request, activationConfiguration.ActivationType, activationConfiguration.MemberInjectionSelectors, members);

            return(members);
        }
Пример #18
0
        /// <summary>
        /// Find matching ConstructorParameterInfo if one exists
        /// </summary>
        /// <param name="parameter"></param>
        /// <param name="configuration"></param>
        /// <returns></returns>
        protected virtual ConstructorParameterInfo FindParameterInfoExpression(ParameterInfo parameter, TypeActivationConfiguration configuration)
        {
            var parameterInfo = parameter.ParameterType.GetTypeInfo();

            var matchedConstructor = configuration.ConstructorParameters.FirstOrDefault(
                p => string.Compare(p.ParameterName, parameter.Name, StringComparison.CurrentCultureIgnoreCase) == 0 &&
                (p.ParameterType == null ||
                 p.ParameterType.GetTypeInfo().IsAssignableFrom(parameterInfo) ||
                 parameterInfo.IsAssignableFrom(p.ParameterType.GetTypeInfo())));

            if (matchedConstructor != null)
            {
                return(matchedConstructor);
            }

            return(configuration.ConstructorParameters.FirstOrDefault(p => string.IsNullOrEmpty(p.ParameterName) &&
                                                                      p.ParameterType != null &&
                                                                      (parameterInfo.IsAssignableFrom(p.ParameterType.GetTypeInfo()) ||
                                                                       p.ParameterType.GetTypeInfo().IsAssignableFrom(parameterInfo))));
        }
Пример #19
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");
        }
Пример #20
0
        /// <summary>
        /// This method is used to pick a constructor from a type
        /// </summary>
        /// <param name="requestingScope"></param>
        /// <param name="configuration"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        protected virtual ConstructorInfo PickConstructor(IInjectionScope requestingScope, TypeActivationConfiguration configuration, IActivationExpressionRequest request)
        {
            if (configuration.SelectedConstructor != null)
            {
                return(configuration.SelectedConstructor);
            }

            var constructors = configuration.ActivationType.GetTypeInfo().DeclaredConstructors.Where(c => c.IsPublic && !c.IsStatic).OrderByDescending(c => c.GetParameters().Length).ToArray();

            if (constructors.Length == 0)
            {
                throw new Exception("Could not find public constructor on type " + configuration.ActivationType.FullName);
            }

            if (constructors.Length == 1)
            {
                return(constructors[0]);
            }

            return(PickConstructor(requestingScope, configuration, request, constructors));
        }
        private Expression CreateLocateExpression(ParameterInfo parameter, IInjectionScope scope, IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration)
        {
            var parameterInfo = FindParameterInfoExpression(parameter, activationConfiguration);

            if (parameterInfo?.ExportFunc is Delegate)
            {
                var newRequest = request.NewRequest(parameter.ParameterType, activationConfiguration.ActivationStrategy,
                                                    activationConfiguration.ActivationType, RequestType.ConstructorParameter, parameter, true);

                var delegateValue = (Delegate)parameterInfo.ExportFunc;

                var expressionCall = ExpressionUtilities.CreateExpressionForDelegate(delegateValue,
                                                                                     activationConfiguration.ExternallyOwned, scope, newRequest);

                var standardParameters = delegateValue.GetMethodInfo()
                                         .GetParameters()
                                         .All(p =>
                {
                    if (p.ParameterType == typeof(IExportLocatorScope))
                    {
                        return(true);
                    }

                    if (p.ParameterType == typeof(IDisposalScope))
                    {
                        return(true);
                    }

                    if (p.ParameterType == typeof(IInjectionContext))
                    {
                        return(true);
                    }

                    return(true);
                });

                if (standardParameters)
                {
                    return(expressionCall.Expression);
                }

                newRequest = request.NewRequest(parameter.ParameterType, activationConfiguration.ActivationStrategy,
                                                activationConfiguration.ActivationType, RequestType.ConstructorParameter, parameter, true);

                var compiledDelegate = request.Services.Compiler.CompileDelegate(scope, expressionCall);

                expressionCall =
                    ExpressionUtilities.CreateExpressionForDelegate(compiledDelegate, false, scope, newRequest);

                return(expressionCall.Expression);
            }

            var closedMethod = DynamicLocateMethodInfo.MakeGenericMethod(parameter.ParameterType);

            return(Expression.Call(Expression.Constant(this),
                                   closedMethod,
                                   request.Constants.ScopeParameter,
                                   request.Constants.RootDisposalScope,
                                   request.Constants.InjectionContextParameter,
                                   Expression.Constant(parameter.Name.ToLowerInvariant()),
                                   Expression.Constant(true),
                                   Expression.Constant(false),
                                   Expression.Default(parameter.ParameterType)));
        }
Пример #22
0
        /// <summary>
        /// Creates trace message for specific constructor
        /// </summary>
        /// <param name="constructor"></param>
        /// <param name="activationConfiguration"></param>
        /// <returns></returns>
        protected virtual string CreateTraceMessageForConstructor(ConstructorInfo constructor, TypeActivationConfiguration activationConfiguration)
        {
            StringBuilder builder = new StringBuilder();

            builder.Append(activationConfiguration.ActivationType.Name);
            builder.Append('(');

            var parameters = constructor.GetParameters();

            for (int i = 0; i < parameters.Length; i++)
            {
                if (i > 0)
                {
                    builder.Append(',');
                }

                builder.Append(parameters[i].ParameterType.Name);
                builder.Append(' ');
                builder.Append(parameters[i].Name);
            }

            builder.Append(')');

            return("Using " + builder);
        }
        private Tuple <ParameterExpression, Expression> CreateCanLocateStatement(ParameterInfo parameter, IInjectionScope scope, IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration)
        {
            var parameterInfo = FindParameterInfoExpression(parameter, activationConfiguration);

            if (parameterInfo != null &&
                (parameterInfo.DefaultValue != null || parameterInfo.ExportFunc != null))
            {
                return(null);
            }

            var closedMethod = DynamicCanLocateMethodInfo.MakeGenericMethod(parameter.ParameterType);

            var callExpression = Expression.Call(Expression.Constant(this),
                                                 closedMethod,
                                                 request.Constants.ScopeParameter,
                                                 request.Constants.InjectionContextParameter,
                                                 Expression.Constant(parameter.Name.ToLowerInvariant()));

            var canVariable = Expression.Variable(typeof(bool));

            return(new Tuple <ParameterExpression, Expression>(canVariable, Expression.Assign(canVariable, callExpression)));
        }
Пример #24
0
        /// <summary>
        /// Get an enumeration of dependencies
        /// </summary>
        /// <param name="configuration">configuration object</param>
        /// <param name="request"></param>
        /// <returns>dependencies</returns>
        public virtual IEnumerable <ActivationStrategyDependency> GetDependencies(TypeActivationConfiguration configuration, IActivationExpressionRequest request)
        {
            var constructor = PickConstructor(request.RequestingScope, configuration, request);

            return(GetDependenciesForConstructor(configuration, request, constructor));
        }
 /// <summary>
 /// This method is called when there are multiple constructors
 /// </summary>
 /// <param name="injectionScope"></param>
 /// <param name="configuration"></param>
 /// <param name="request"></param>
 /// <param name="constructors"></param>
 /// <returns></returns>
 protected override ConstructorInfo PickConstructor(IInjectionScope injectionScope, TypeActivationConfiguration configuration,
                                                    IActivationExpressionRequest request, ConstructorInfo[] constructors)
 {
     return(constructors.OrderByDescending(c => c.GetParameters().Length).First());
 }
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="activationType">type to activate</param>
        /// <param name="injectionScope">owning injection scope</param>
        protected ConfigurableActivationStrategy(Type activationType, IInjectionScope injectionScope)
        {
            ActivationConfiguration = new TypeActivationConfiguration(activationType, this);

            InjectionScope = injectionScope;
        }
Пример #27
0
        /// <summary>
        /// Method to pick the constructor to use based on how the container is configured
        /// </summary>
        /// <param name="injectionScope">injection scope</param>
        /// <param name="configuration">type configuration</param>
        /// <param name="request">activation request</param>
        /// <returns></returns>
        protected virtual ConstructorInfo PickConstructor(IInjectionScope injectionScope, TypeActivationConfiguration configuration, IActivationExpressionRequest request)
        {
            if (configuration.SelectedConstructor != null)
            {
                return(configuration.SelectedConstructor);
            }

            var constructors = configuration.ActivationType.GetTypeInfo().DeclaredConstructors.Where(c => c.IsPublic && !c.IsStatic).OrderByDescending(c => c.GetParameters().Length).ToArray();

            if (constructors.Length == 0)
            {
                throw new Exception("Could not find public constructor on type " + configuration.ActivationType.FullName);
            }

            if (constructors.Length == 1)
            {
                return(constructors[0]);
            }

            switch (injectionScope.ScopeConfiguration.Behaviors.ConstructorSelection)
            {
            case ConstructorSelectionMethod.LeastParameters:
                return(constructors.Last());

            case ConstructorSelectionMethod.MostParameters:
                return(constructors.First());

            case ConstructorSelectionMethod.BestMatch:
                return(MatchBestConstructor(injectionScope, configuration, request, constructors));

            default:
                throw new Exception("Unknown constrcutor selection type");
            }
        }