예제 #1
0
        /// <summary>
        /// Get activation expression for export strategies
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="request"></param>
        /// <param name="arrayElementType"></param>
        /// <returns></returns>
        protected virtual List <IActivationExpressionResult> GetActivationExpressionResultsFromStrategies(IInjectionScope scope, IActivationExpressionRequest request,
                                                                                                          Type arrayElementType)
        {
            var parentStrategy = GetRequestingStrategy(request);

            List <object> keys        = null;
            var           collection  = scope.StrategyCollectionContainer.GetActivationStrategyCollection(arrayElementType);
            var           expressions = new List <IActivationExpressionResult>();

            if (request.LocateKey != null)
            {
                var enumerableKey = request.LocateKey as IEnumerable;

                if (enumerableKey != null && !(request.LocateKey is string))
                {
                    keys = new List <object>();

                    foreach (var value in enumerableKey)
                    {
                        keys.Add(value);
                    }
                }
                else
                {
                    keys = new List <object> {
                        request.LocateKey
                    };
                }
            }

            if (collection != null)
            {
                if (keys != null)
                {
                    for (var i = 0; i < keys.Count;)
                    {
                        var strategy = collection.GetKeyedStrategy(keys[i]);

                        if (strategy != null && parentStrategy != strategy)
                        {
                            var newRequest = request.NewRequest(arrayElementType, request.RequestingStrategy, request.RequestingStrategy?.ActivationType, request.RequestType,
                                                                request.Info, true);

                            var expression = strategy.GetActivationExpression(scope, newRequest);

                            if (expression != null)
                            {
                                expressions.Add(expression);
                                keys.RemoveAt(i);
                            }
                            else
                            {
                                i++;
                            }
                        }
                        else
                        {
                            i++;
                        }
                    }
                }
                else
                {
                    foreach (var strategy in collection.GetStrategies())
                    {
                        // skip as part of the composite pattern
                        if (strategy == parentStrategy)
                        {
                            continue;
                        }

                        // filter strategies
                        if (request.Filter != null && !request.Filter(strategy))
                        {
                            continue;
                        }

                        var newRequest = request.NewRequest(arrayElementType, request.RequestingStrategy, request.RequestingStrategy?.ActivationType, request.RequestType,
                                                            request.Info, true);

                        var expression = strategy.GetActivationExpression(scope, newRequest);

                        if (expression != null)
                        {
                            expressions.Add(expression);
                        }
                    }
                }
            }

            // check for generic
            if (arrayElementType.IsConstructedGenericType)
            {
                var genericType = arrayElementType.GetGenericTypeDefinition();

                var strategies = scope.StrategyCollectionContainer.GetActivationStrategyCollection(genericType);

                if (strategies != null)
                {
                    if (keys != null)
                    {
                        for (var i = 0; i < keys.Count;)
                        {
                            var strategy = strategies.GetKeyedStrategy(keys[i]);

                            if (strategy != null && strategy != parentStrategy)
                            {
                                var newRequest = request.NewRequest(arrayElementType, request.RequestingStrategy,
                                                                    request.RequestingStrategy?.ActivationType, request.RequestType,
                                                                    request.Info, true);

                                var expression = strategy.GetActivationExpression(scope, newRequest);

                                if (expression != null)
                                {
                                    expressions.Add(expression);
                                    keys.RemoveAt(i);
                                }
                                else
                                {
                                    i++;
                                }
                            }
                            else
                            {
                                i++;
                            }
                        }
                    }
                    else
                    {
                        foreach (var strategy in strategies.GetStrategies())
                        {
                            // skip as part of the composite pattern
                            if (strategy == parentStrategy)
                            {
                                continue;
                            }

                            // filter strategies
                            if (request.Filter != null && !request.Filter(strategy))
                            {
                                continue;
                            }

                            var newRequest = request.NewRequest(arrayElementType, request.RequestingStrategy,
                                                                request.RequestingStrategy?.ActivationType, request.RequestType,
                                                                request.Info, true);

                            var expression = strategy.GetActivationExpression(scope, newRequest);

                            if (expression != null)
                            {
                                expressions.Add(expression);
                            }
                        }
                    }
                }
            }

            if (expressions.Count == 0)
            {
                ProcessWrappers(scope, arrayElementType, request, expressions);
            }

            return(expressions);
        }
예제 #2
0
        /// <summary>
        /// Sets up wrappers for request
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public bool SetupWrappersForRequest(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 = GetWrappedTypeFromStrategiesCollection(scope, wrappedType);

                    if (collection == null)
                    {
                        lock (scope.GetLockObject(InjectionScope.ActivationStrategyAddLockName))
                        {
                            var newRequest = request.NewRequest(wrappedType, request.RequestingStrategy,
                                                                request.InjectedType, request.RequestType, request.Info, false, true);

                            request.Services.Compiler.ProcessMissingStrategyProviders(scope, newRequest);
                        }

                        collection = GetWrappedTypeFromStrategiesCollection(scope, wrappedType);
                    }

                    if (collection != null)
                    {
                        if (request.LocateKey != null)
                        {
                            var strategy = collection.GetKeyedStrategy(request.LocateKey);

                            if (strategy != null)
                            {
                                wrappers = ImmutableLinkedList <IActivationPathNode> .Empty
                                           .Add(new WrapperActivationPathNode(strategy, wrappedType, null))
                                           .AddRange(wrappers.Reverse());
                            }
                        }
                        else
                        {
                            var primary = request.Filter == null?collection.GetPrimary() : null;

                            if (primary != null && primary != request.RequestingStrategy)
                            {
                                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.RequestingStrategy != strategy &&
                                        (request.Filter == null || request.Filter(strategy)))
                                    {
                                        wrappers = ImmutableLinkedList <IActivationPathNode> .Empty
                                                   .Add(new WrapperActivationPathNode(strategy, wrappedType, null))
                                                   .AddRange(wrappers.Reverse());
                                    }
                                }
                            }
                        }
                    }
                    else if (!wrappedType.IsArray &&
                             (!wrappedType.IsConstructedGenericType || wrappedType.GetGenericTypeDefinition() != typeof(IEnumerable <>)))
                    {
                        return(false);
                    }
                }

                request.SetWrapperPath(wrappers);

                return(true);
            }

            return(false);
        }
예제 #3
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);
        }