Пример #1
0
        /// <summary>
        /// Gets the target which can be used to build an instance of <paramref name="type"/>.
        /// </summary>
        /// <param name="type">Required.  The type for which a target is to be obtained.  Because of the
        /// restrictions placed on the <see cref="ITarget.DeclaredType"/> of the targets that can actually
        /// be registered into this container, the function will only ever return anything if <paramref name="type"/>
        /// is a closed generic type whose definition equals <see cref="GenericType"/>.</param>
        /// <remarks>Targets which have been registered specifically against the exact closed generic type
        /// represented by <paramref name="type"/> take precedence over any targets which have been registered
        /// against the open generic type <see cref="GenericType"/>.</remarks>
        public override ITarget Fetch(Type type)
        {
            // don't bother checking type validity, just find the container entry with the
            // given type and return the result of its fetch function.
            // If we don't find one - then we return the targets that have been registered against the
            // open generic type definition.
            return(this._caches.FetchCache.GetOrAdd(type, t =>
            {
                ITarget baseResult = null;
                var typeSelector = Root.SelectTypes(t);
                foreach (var searchType in typeSelector)
                {
                    if ((baseResult = base.Fetch(searchType)) != null)
                    {
                        if (typeSelector.IsVariantMatch(type, searchType))
                        {
                            return VariantMatchTarget.Wrap(baseResult, type, searchType);
                        }
                        else
                        {
                            return baseResult;
                        }
                    }
                }

                // no direct match for any of the search types in our dictionary - so resort to the
                // targets that have been registered directly against the open generic type.
                return Targets.Fetch(t);
            }));
        }
Пример #2
0
        private IEnumerable <ITarget> FetchAllWorker(Type type)
        {
            bool matchAll     = Root.GetOption(type, Options.FetchAllMatchingGenerics.Default);
            bool foundOne     = false;
            var  typeSelector = Root.SelectTypes(type);

            // all generics are returned in descending order of specificity
            foreach (var searchType in typeSelector)
            {
                foreach (var result in base.FetchAll(searchType))
                {
                    if (!matchAll && !foundOne)
                    {
                        foundOne = true;
                    }

                    yield return(typeSelector.IsVariantMatch(type, searchType) ? VariantMatchTarget.Wrap(result, type, searchType) : result);
                }

                if (!matchAll && foundOne)
                {
                    yield break;
                }
            }

            foreach (var result in Targets.FetchAll(type))
            {
                yield return(result);
            }
        }
Пример #3
0
 internal static IEnumerable <ITarget> FetchAllCompatibleTargetsInternal(this IRootTargetContainer rootContainer, Type serviceType)
 {
     return(rootContainer.FetchAll(serviceType)
            .Concat(rootContainer.GetKnownCompatibleTypes(serviceType)
                    .SelectMany(compatibleType => rootContainer.FetchAll(compatibleType)
                                .Select(t => VariantMatchTarget.Wrap(t, serviceType, compatibleType))
                                )).Distinct(TargetIdentityComparer.Instance));
 }