/// <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)); }
/// <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))); }
/// <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)); }
/// <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); }
/// <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)); }
/// <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); }
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)); }
/// <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); }
/// <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); }
/// <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)))); }
/// <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"); }
/// <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))); }
/// <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))); }
/// <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; }
/// <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"); } }