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

            SetDefaultValue(parameter, parameterInfo, newRequest);

            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));
        }
示例#5
0
        /// <summary>
        /// Create expression to call func
        /// </summary>
        /// <param name="strategy"></param>
        /// <param name="parameter"></param>
        /// <param name="parameterInfo"></param>
        /// <param name="injectionScope"></param>
        /// <param name="request"></param>
        /// <param name="configurationExternallyOwned"></param>
        /// <returns></returns>
        protected IActivationExpressionResult CallExportFunc(IActivationStrategy strategy, ParameterInfo parameter, ConstructorParameterInfo parameterInfo, IInjectionScope injectionScope, IActivationExpressionRequest request, bool configurationExternallyOwned)
        {
            var exportDelegate = parameterInfo.ExportFunc as Delegate;

            if (exportDelegate == null)
            {
                throw new ArgumentException($"Parameter Info {parameterInfo.ParameterName} is not delegate", nameof(parameterInfo));
            }

            var newRequest = request.NewRequest(parameter.ParameterType, strategy, strategy.ActivationType,
                                                RequestType.ConstructorParameter, parameter, false, true);

            return(ExpressionUtilities.CreateExpressionForDelegate(exportDelegate, ShouldTrackDisposable(configurationExternallyOwned, injectionScope, strategy), injectionScope, newRequest, strategy));
        }
示例#6
0
 /// <summary>
 /// Get Methods to inject
 /// </summary>
 /// <param name="type">type being activated</param>
 /// <param name="injectionScope">injection scope</param>
 /// <param name="request">request</param>
 /// <returns>methods being injected</returns>
 public IEnumerable <MethodInjectionInfo> GetMethods(Type type, IInjectionScope injectionScope, IActivationExpressionRequest request)
 {
     yield break;
 }
示例#7
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);
 }
示例#8
0
        /// <summary>
        /// Provide an expression that uses the lifestyle
        /// </summary>
        /// <param name="scope">scope for the strategy</param>
        /// <param name="request">activation request</param>
        /// <param name="activationExpression">expression to create strategy type</param>
        /// <returns></returns>
        public IActivationExpressionResult ProvideLifestyleExpression(IInjectionScope scope, IActivationExpressionRequest request, Func <IActivationExpressionRequest, IActivationExpressionResult> activationExpression)
        {
            if (CompiledDelegate == null)
            {
                // new request as we don't want to carry any info over from parent request
                var newRequest = request.NewRootedRequest(request.ActivationType, scope, true);

                var localDelegate = request.Services.Compiler.CompileDelegate(scope, activationExpression(newRequest));

                Interlocked.CompareExchange(ref CompiledDelegate, localDelegate, null);
            }

            var getValueFromScopeMethod =
                typeof(SingletonPerNamedScopeLifestyle).GetRuntimeMethod("GetValueFromScope",
                                                                         new[]
            {
                typeof(IExportLocatorScope),
                typeof(ActivationStrategyDelegate),
                typeof(string),
                typeof(string),
                typeof(StaticInjectionContext)
            });

            var closedMethod = getValueFromScopeMethod.MakeGenericMethod(request.ActivationType);

            var expression = Expression.Call(closedMethod,
                                             request.Constants.ScopeParameter,
                                             Expression.Constant(CompiledDelegate),
                                             Expression.Constant(UniqueId),
                                             Expression.Constant(_scopeName),
                                             Expression.Constant(request.GetStaticInjectionContext()));

            return(request.Services.Compiler.CreateNewResult(request, expression));
        }
示例#9
0
        /// <summary>
        /// Get a list of member injection info for a specific type
        /// </summary>
        /// <param name="type">type being activated</param>
        /// <param name="injectionScope">injection scope</param>
        /// <param name="request">request</param>
        /// <returns>members being injected</returns>
        public IEnumerable <MemberInjectionInfo> GetPropertiesAndFields(Type type, IInjectionScope injectionScope, IActivationExpressionRequest request)
        {
            foreach (var property in type.GetRuntimeProperties())
            {
                if (!property.CanWrite || !property.SetMethod.IsPublic || property.SetMethod.IsStatic)
                {
                    continue;
                }

                if (ReflectionService.CheckTypeIsBasedOnAnotherType(property.PropertyType, _memberType))
                {
                    if (_filter == null || _filter(property))
                    {
                        yield return(new MemberInjectionInfo {
                            MemberInfo = property, LocateKey = LocateKey, IsRequired = IsRequired
                        });
                    }
                }
            }

            foreach (var field in type.GetRuntimeFields())
            {
                if (!field.IsPublic || field.IsStatic)
                {
                    continue;
                }
                if (ReflectionService.CheckTypeIsBasedOnAnotherType(field.FieldType, _memberType))
                {
                    if (_filter == null || _filter(field))
                    {
                        yield return(new MemberInjectionInfo {
                            MemberInfo = field, LocateKey = LocateKey, IsRequired = IsRequired
                        });
                    }
                }
            }
        }
        /// <summary>
        /// Create expression that is implemented in child class
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="request"></param>
        /// <param name="lifestyle"></param>
        /// <returns></returns>
        protected override IActivationExpressionResult CreateExpression(IInjectionScope scope, IActivationExpressionRequest request,
                                                                        ICompiledLifestyle lifestyle)
        {
            if (lifestyle == null)
            {
                return(CreateExpression(scope, request));
            }

            return(lifestyle.ProvideLifestyleExpression(scope, request,
                                                        expressionRequest => CreateExpression(scope, expressionRequest)));
        }
 /// <summary>
 /// Create expression that calls a delegate
 /// </summary>
 /// <param name="scope">scope for the request</param>
 /// <param name="request">activation request</param>
 /// <returns></returns>
 protected virtual IActivationExpressionResult CreateExpression(IInjectionScope scope,
                                                                IActivationExpressionRequest request)
 {
     return(ExpressionUtilities.CreateExpressionForDelegate(DelegateInstance, ShouldTrackDisposable(scope), scope, request));
 }
        /// <summary>
        /// Get an activation expression for this strategy
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public override IActivationExpressionResult GetActivationExpression(IInjectionScope scope, IActivationExpressionRequest request)
        {
            var invokeMethod = request.ActivationType.GetTypeInfo().GetDeclaredMethod("Invoke");

            var list = new List <Type>(invokeMethod.GetParameters().Select(p => p.ParameterType));

            list.Add(invokeMethod.ReturnType);
            list.Add(request.ActivationType);

            var closedClass = typeof(DelegateExpression <, , ,>).MakeGenericType(list.ToArray());

            var closedMethod = closedClass.GetRuntimeMethod("CreateDelegate", new[] { typeof(IExportLocatorScope), typeof(IDisposalScope), typeof(IInjectionContext) });

            var instance = Activator.CreateInstance(closedClass, scope, request, request.Services.InjectionContextCreator, this);

            var callExpression =
                Expression.Call(Expression.Constant(instance), closedMethod, request.Constants.ScopeParameter,
                                request.DisposalScopeExpression, request.Constants.InjectionContextParameter);

            return(request.Services.Compiler.CreateNewResult(request, callExpression));
        }
 /// <summary>
 /// Get an activation expression for this strategy
 /// </summary>
 /// <param name="scope"></param>
 /// <param name="request"></param>
 /// <returns></returns>
 public abstract IActivationExpressionResult GetActivationExpression(IInjectionScope scope, IActivationExpressionRequest request);
 /// <summary>
 /// Get an activation expression for this strategy
 /// </summary>
 /// <param name="scope"></param>
 /// <param name="request"></param>
 /// <param name="lifestyle"></param>
 /// <returns></returns>
 public abstract IActivationExpressionResult GetDecoratorActivationExpression(IInjectionScope scope,
                                                                              IActivationExpressionRequest request,
                                                                              ICompiledLifestyle lifestyle);
示例#15
0
 /// <summary>
 /// Default constructor
 /// </summary>
 /// <param name="scope"></param>
 /// <param name="request"></param>
 /// <param name="activationStrategy"></param>
 public LazyExpression(IInjectionScope scope, IActivationExpressionRequest request, IActivationStrategy activationStrategy)
 {
     _scope              = scope;
     _request            = request;
     _activationStrategy = activationStrategy;
 }
示例#16
0
        /// <summary>
        /// Get an activation expression for this strategy
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public override IActivationExpressionResult GetActivationExpression(IInjectionScope scope, IActivationExpressionRequest request)
        {
            var closedClass = typeof(LazyExpression <>).MakeGenericType(request.ActivationType.GenericTypeArguments);

            var closedMethod = closedClass.GetRuntimeMethod(nameof(LazyExpression <object> .CreateLazy), new[] { typeof(IExportLocatorScope), typeof(IDisposalScope), typeof(IInjectionContext) });

            var instance = Activator.CreateInstance(closedClass, scope, request, this);

            request.RequireExportScope();
            request.RequireDisposalScope();

            var callExpression =
                Expression.Call(Expression.Constant(instance), closedMethod, request.ScopeParameter,
                                request.DisposalScopeExpression, request.InjectionContextParameter);

            request.RequireInjectionContext();

            return(request.Services.Compiler.CreateNewResult(request, callExpression));
        }