Esempio n. 1
0
        /// <summary>
        /// Get list of expressions to populate array
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="request"></param>
        /// <param name="arrayElementType"></param>
        /// <returns></returns>
        protected virtual List <IActivationExpressionResult> GetArrayExpressionList(IInjectionScope scope, IActivationExpressionRequest request, Type arrayElementType)
        {
            var expressions = GetActivationExpressionResultsFromStrategies(scope, request, arrayElementType);

            if (expressions.Count != 0)
            {
                return(expressions);
            }

            lock (scope.GetLockObject(InjectionScope.ActivationStrategyAddLockName))
            {
                expressions = GetActivationExpressionResultsFromStrategies(scope, request, arrayElementType);

                if (expressions.Count != 0)
                {
                    return(expressions);
                }

                request.Services.Compiler.ProcessMissingStrategyProviders(scope, request.Services.Compiler.CreateNewRequest(arrayElementType, request.ObjectGraphDepth + 1, scope));

                expressions = GetActivationExpressionResultsFromStrategies(scope, request, arrayElementType);
            }

            return(expressions);
        }
Esempio n. 2
0
        /// <summary>
        /// Process wrappers looking for matching type
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="arrayElementType"></param>
        /// <param name="request"></param>
        /// <param name="expressions"></param>
        protected virtual void ProcessWrappers(IInjectionScope scope, Type arrayElementType, IActivationExpressionRequest request, List <IActivationExpressionResult> expressions)
        {
            Type wrappedType;
            var  wrappers = _wrapperExpressionCreator.GetWrappers(scope, arrayElementType, request, out wrappedType);

            if (wrappers != ImmutableLinkedList <IActivationPathNode> .Empty)
            {
                wrappers = wrappers.Reverse();

                GetExpressionsFromCollections(scope, arrayElementType, request, expressions, wrappedType, wrappers);

                if (expressions.Count == 0)
                {
                    lock (scope.GetLockObject(InjectionScope.ActivationStrategyAddLockName))
                    {
                        GetExpressionsFromCollections(scope, arrayElementType, request, expressions, wrappedType, wrappers);

                        if (expressions.Count == 0)
                        {
                            var newRequest = request.NewRequest(arrayElementType, request.RequestingStrategy, request.RequestingStrategy?.ActivationType, RequestType.Other, null, true);

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

                            GetExpressionsFromCollections(scope, arrayElementType, request, expressions, wrappedType, wrappers);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Find a delegate for a specific type
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="locateType"></param>
        /// <param name="consider"></param>
        /// <param name="key"></param>
        /// <param name="injectionContext"></param>
        /// <param name="checkMissing"></param>
        /// <returns></returns>
        public virtual ActivationStrategyDelegate FindDelegate(IInjectionScope scope, Type locateType, ActivationStrategyFilter consider, object key, IInjectionContext injectionContext, bool checkMissing)
        {
            var activationDelegate = LocateStrategyFromCollectionContainers(scope, locateType, consider, key, injectionContext);

            if (activationDelegate != null)
            {
                return(activationDelegate);
            }

            activationDelegate = LocateEnumerableStrategy(scope, locateType, consider, key);

            if (activationDelegate != null)
            {
                return(activationDelegate);
            }

            if (checkMissing)
            {
                lock (scope.GetLockObject(InjectionScope.ActivationStrategyAddLockName))
                {
                    activationDelegate = LocateStrategyFromCollectionContainers(scope, locateType, consider, key, injectionContext);

                    if (activationDelegate != null)
                    {
                        return(activationDelegate);
                    }

                    var request = CreateNewRequest(locateType, 1, scope);

                    request.SetFilter(consider);

                    ProcessMissingStrategyProviders(scope, request);

                    activationDelegate = LocateStrategyFromCollectionContainers(scope, locateType, consider, key, injectionContext);

                    if (activationDelegate != null)
                    {
                        return(activationDelegate);
                    }
                }
            }

            return(null);
        }
Esempio n. 4
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);
        }
        /// <summary>
        /// Get a linq expression to satisfy the request
        /// </summary>
        /// <param name="scope">scope</param>
        /// <param name="request">request</param>
        /// <returns></returns>
        public virtual IActivationExpressionResult GetActivationExpression(IInjectionScope scope, IActivationExpressionRequest request)
        {
            var activationExpressionResult = GetValueFromRequest(scope, request, request.ActivationType, null);

            if (activationExpressionResult != null)
            {
                return(activationExpressionResult);
            }

            activationExpressionResult = GetValueFromInjectionValueProviders(scope, request);

            if (activationExpressionResult != null)
            {
                return(activationExpressionResult);
            }

            activationExpressionResult = GetActivationExpressionFromStrategies(scope, request);

            if (activationExpressionResult != null)
            {
                return(activationExpressionResult);
            }

            if (request.ActivationType.IsArray)
            {
                return(ArrayExpressionCreator.GetArrayExpression(scope, request));
            }

            if (request.ActivationType.IsConstructedGenericType &&
                request.ActivationType.GetGenericTypeDefinition() == typeof(IEnumerable <>))
            {
                return(EnumerableExpressionCreator.GetEnumerableExpression(scope, request, ArrayExpressionCreator));
            }

            var wrapperResult = WrapperExpressionCreator.GetActivationExpression(scope, request);

            if (wrapperResult != null)
            {
                return(wrapperResult);
            }

            if (scope.MissingExportStrategyProviders.Any())
            {
                lock (scope.GetLockObject(InjectionScope.ActivationStrategyAddLockName))
                {
                    activationExpressionResult = GetActivationExpressionFromStrategies(scope, request);

                    if (activationExpressionResult != null)
                    {
                        return(activationExpressionResult);
                    }

                    wrapperResult = WrapperExpressionCreator.GetActivationExpression(scope, request);

                    if (wrapperResult != null)
                    {
                        return(wrapperResult);
                    }

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

                    activationExpressionResult = GetActivationExpressionFromStrategies(scope, request);

                    if (activationExpressionResult != null)
                    {
                        return(activationExpressionResult);
                    }

                    wrapperResult = WrapperExpressionCreator.GetActivationExpression(scope, request);

                    if (wrapperResult != null)
                    {
                        return(wrapperResult);
                    }
                }
            }

            var parent = scope.Parent as IInjectionScope;

            if (parent != null)
            {
                return(GetActivationExpression(parent, request));
            }

            return(GetValueFromInjectionContext(scope, request));
        }