예제 #1
0
        /// <summary>
        /// Get an activation expression for a request
        /// </summary>
        /// <param name="scope">scope for request</param>
        /// <param name="request">request</param>
        /// <returns></returns>
        public IActivationExpressionResult GetActivationExpression(IInjectionScope scope, IActivationExpressionRequest request)
        {
            if (SetupWrappersForRequest(scope, request))
            {
                var wrapper = request.PopWrapperPathNode();

                return(wrapper.GetActivationExpression(scope, request));
            }

            return(null);
        }
예제 #2
0
        /// <summary>
        /// Get expression result from request
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="request"></param>
        /// <param name="activationType"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        protected virtual IActivationExpressionResult GetValueFromRequest(IInjectionScope scope,
                                                                          IActivationExpressionRequest request,
                                                                          Type activationType,
                                                                          object key)
        {
            var knownValues =
                request.KnownValueExpressions.Where(
                    v => activationType.GetTypeInfo().IsAssignableFrom(v.ActivationType.GetTypeInfo())).ToArray();

            if (knownValues.Length > 0)
            {
                if (knownValues.Length == 1)
                {
                    return(knownValues[0].ValueExpression(request));
                }

                if (key != null)
                {
                    IKnownValueExpression knownValue;

                    if (key is string keyString)
                    {
                        knownValue =
                            knownValues.FirstOrDefault(v =>
                                                       string.Compare(keyString, v.Key as string, StringComparison.CurrentCultureIgnoreCase) == 0);
                    }
                    else
                    {
                        knownValue = knownValues.FirstOrDefault(v => v.Key == key);
                    }

                    if (knownValue != null)
                    {
                        return(knownValue.ValueExpression(request));
                    }
                }

                if (request.Info is MemberInfo memberInfo)
                {
                    var knownValue = knownValues.FirstOrDefault(v => Equals(v.Key, memberInfo.Name));

                    if (knownValue != null)
                    {
                        return(knownValue.ValueExpression(request));
                    }
                }

                if (request.Info is ParameterInfo parameterInfo)
                {
                    var knownValue = knownValues.FirstOrDefault(v => Equals(v.Key, parameterInfo.Name));

                    if (knownValue != null)
                    {
                        return(knownValue.ValueExpression(request));
                    }

                    knownValue = knownValues.FirstOrDefault(v =>
                                                            Equals(v.Position.GetValueOrDefault(-1), parameterInfo.Position));

                    if (knownValue != null)
                    {
                        return(knownValue.ValueExpression(request));
                    }
                }

                return(knownValues[0].ValueExpression(request));
            }

            if (request.WrapperPathNode != null)
            {
                var configuration = request.WrapperPathNode.Strategy.GetActivationConfiguration(activationType);

                if (activationType.GetTypeInfo().IsAssignableFrom(configuration.ActivationType.GetTypeInfo()))
                {
                    var wrapper = request.PopWrapperPathNode();

                    return(ProcessPathNode(scope, request, activationType, wrapper));
                }
            }
            else if (request.DecoratorPathNode != null)
            {
                var configuration = request.DecoratorPathNode.Strategy.GetActivationConfiguration(activationType);

                if (activationType.GetTypeInfo().IsAssignableFrom(configuration.ActivationType.GetTypeInfo()))
                {
                    var decorator = request.PopDecoratorPathNode();

                    return(ProcessPathNode(scope, request, activationType, decorator));
                }
            }

            if (request.ActivationType == typeof(IInjectionScope))
            {
                if (!scope.ScopeConfiguration.Behaviors.AllowInjectionScopeLocation)
                {
                    throw new ImportInjectionScopeException(request.GetStaticInjectionContext());
                }

                var method = typeof(IExportLocatorScopeExtensions).GetRuntimeMethod("GetInjectionScope", new[] { typeof(IExportLocatorScope) });

                var expression = Expression.Call(method, request.ScopeParameter);

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

            if (request.ActivationType == typeof(IExportLocatorScope) ||
                request.ActivationType == typeof(ILocatorService))
            {
                return(request.Services.Compiler.CreateNewResult(request, request.ScopeParameter));
            }

            if (request.ActivationType == typeof(IDisposalScope) ||
                (request.ActivationType == typeof(IDisposable) &&
                 request.RequestingScope.ScopeConfiguration.InjectIDisposable))
            {
                return(request.Services.Compiler.CreateNewResult(request, request.DisposalScopeExpression));
            }

            if (request.ActivationType == typeof(IInjectionContext))
            {
                request.RequireInjectionContext();

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

            if (request.ActivationType == typeof(StaticInjectionContext))
            {
                var staticContext = request.Parent != null?
                                    request.Parent.GetStaticInjectionContext() :
                                        request.GetStaticInjectionContext();

                return(request.Services.Compiler.CreateNewResult(request, Expression.Constant(staticContext)));
            }

            if (request.IsDynamic)
            {
                var dynamicMethod =
                    typeof(ActivationExpressionBuilder).GetRuntimeMethod("GetDynamicValue",
                                                                         new[]
                {
                    typeof(IExportLocatorScope),
                    typeof(IDisposalScope),
                    typeof(StaticInjectionContext),
                    typeof(IInjectionContext),
                    typeof(object),
                    typeof(bool),
                    typeof(bool),
                    typeof(object)
                });

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

                Expression defaultExpression =
                    Expression.Constant(request.DefaultValue?.DefaultValue, typeof(object));

                var expression = Expression.Call(closedMethod,
                                                 request.ScopeParameter,
                                                 request.DisposalScopeExpression,
                                                 Expression.Constant(request.GetStaticInjectionContext()),
                                                 request.InjectionContextParameter,
                                                 Expression.Constant(request.LocateKey, typeof(object)),
                                                 Expression.Constant(request.IsRequired),
                                                 Expression.Constant(request.DefaultValue != null),
                                                 defaultExpression);

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

            return(null);
        }
예제 #3
0
        /// <summary>
        /// Get expression result from request
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="request"></param>
        /// <param name="activationType"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        protected virtual IActivationExpressionResult GetValueFromRequest(IInjectionScope scope,
                                                                          IActivationExpressionRequest request,
                                                                          Type activationType,
                                                                          object key)
        {
            var knownValue =
                request.KnownValueExpressions.FirstOrDefault(
                    v => activationType.GetTypeInfo().IsAssignableFrom(v.ActivationType.GetTypeInfo()));

            if (knownValue != null)
            {
                return(knownValue.ValueExpression(request));
            }

            if (request.WrapperPathNode != null)
            {
                var configuration = request.WrapperPathNode.Strategy.GetActivationConfiguration(activationType);

                if (activationType.GetTypeInfo().IsAssignableFrom(configuration.ActivationType.GetTypeInfo()))
                {
                    var wrapper = request.PopWrapperPathNode();

                    return(ProcessPathNode(scope, request, activationType, wrapper));
                }
            }
            else if (request.DecoratorPathNode != null)
            {
                var configuration = request.DecoratorPathNode.Strategy.GetActivationConfiguration(activationType);

                if (activationType.GetTypeInfo().IsAssignableFrom(configuration.ActivationType.GetTypeInfo()))
                {
                    var decorator = request.PopDecoratorPathNode();

                    return(ProcessPathNode(scope, request, activationType, decorator));
                }
            }

            if (request.ActivationType == typeof(IInjectionScope))
            {
                if (!scope.ScopeConfiguration.Behaviors.AllowInjectionScopeLocation)
                {
                    throw new ImportInjectionScopeException(request.GetStaticInjectionContext());
                }

                var method = typeof(IExportLocatorScopeExtensions).GetRuntimeMethod("GetInjectionScope", new[] { typeof(IExportLocatorScope) });

                var expression = Expression.Call(method, request.Constants.ScopeParameter);

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

            if (request.ActivationType == typeof(IExportLocatorScope) ||
                request.ActivationType == typeof(ILocatorService))
            {
                return(request.Services.Compiler.CreateNewResult(request, request.Constants.ScopeParameter));
            }

            if (request.ActivationType == typeof(IInjectionContext))
            {
                request.RequireInjectionContext();

                return(request.Services.Compiler.CreateNewResult(request, request.Constants.InjectionContextParameter));
            }

            if (request.ActivationType == typeof(StaticInjectionContext))
            {
                var staticContext = request.Parent != null?
                                    request.Parent.GetStaticInjectionContext() :
                                        request.GetStaticInjectionContext();

                return(request.Services.Compiler.CreateNewResult(request, Expression.Constant(staticContext)));
            }

            if (request.IsDynamic)
            {
                var dynamicMethod =
                    typeof(ActivationExpressionBuilder).GetRuntimeMethod("GetDynamicValue",
                                                                         new[]
                {
                    typeof(IExportLocatorScope),
                    typeof(IDisposalScope),
                    typeof(StaticInjectionContext),
                    typeof(IInjectionContext),
                    typeof(object),
                    typeof(bool),
                    typeof(bool),
                    typeof(object)
                });

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

                Expression defaultExpression =
                    Expression.Constant(request.DefaultValue?.DefaultValue, typeof(object));

                var expression = Expression.Call(closedMethod,
                                                 request.Constants.ScopeParameter,
                                                 request.DisposalScopeExpression,
                                                 Expression.Constant(request.GetStaticInjectionContext()),
                                                 request.Constants.InjectionContextParameter,
                                                 Expression.Constant(request.LocateKey, typeof(object)),
                                                 Expression.Constant(request.IsRequired),
                                                 Expression.Constant(request.DefaultValue != null),
                                                 defaultExpression);

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

            return(null);
        }
예제 #4
0
        /// <summary>
        /// Get an activation expression for a request
        /// </summary>
        /// <param name="scope">scope for request</param>
        /// <param name="request">request</param>
        /// <returns></returns>
        public IActivationExpressionResult GetActivationExpression(IInjectionScope scope, IActivationExpressionRequest request)
        {
            Type wrappedType;

            var wrappers = GetWrappers(scope, request.ActivationType, request, out wrappedType);

            if (wrappers != ImmutableLinkedList <IActivationPathNode> .Empty)
            {
                if (request.DecoratorPathNode != null &&
                    wrappedType.GetTypeInfo().IsAssignableFrom(request.DecoratorPathNode.Strategy.ActivationType.GetTypeInfo()))
                {
                    var decorator = request.PopDecoratorPathNode();

                    wrappers = ImmutableLinkedList <IActivationPathNode> .Empty.Add(decorator).AddRange(wrappers.Reverse());
                }
                else
                {
                    var collection = scope.StrategyCollectionContainer.GetActivationStrategyCollection(wrappedType);

                    if (collection == null && wrappedType.IsConstructedGenericType)
                    {
                        var generic = wrappedType.GetGenericTypeDefinition();

                        collection = scope.StrategyCollectionContainer.GetActivationStrategyCollection(generic);
                    }

                    if (collection != null)
                    {
                        var primary = request.Filter == null?collection.GetPrimary() : null;

                        if (primary != null)
                        {
                            wrappers = ImmutableLinkedList <IActivationPathNode> .Empty.Add(new WrapperActivationPathNode(primary, wrappedType, null)).AddRange(wrappers.Reverse());
                        }
                        else
                        {
                            foreach (var strategy in collection.GetStrategies())
                            {
                                var pass = true;

                                if (strategy.HasConditions)
                                {
                                    foreach (var condition in strategy.Conditions)
                                    {
                                        if (!condition.MeetsCondition(strategy, request.GetStaticInjectionContext()))
                                        {
                                            pass = false;
                                            break;
                                        }
                                    }
                                }

                                if (pass &&
                                    (request.Filter == null || request.Filter(strategy)))
                                {
                                    wrappers = ImmutableLinkedList <IActivationPathNode> .Empty.Add(new WrapperActivationPathNode(strategy, wrappedType, null)).AddRange(wrappers.Reverse());
                                }
                            }
                        }
                    }
                    else
                    {
                        return(null);
                    }
                }

                request.SetWrapperPath(wrappers);

                var wrapper = request.PopWrapperPathNode();

                return(wrapper.GetActivationExpression(scope, request));
            }

            return(null);
        }