Пример #1
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);
        }
Пример #2
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);
        }