Exemple #1
0
        private IEnumerable <IXmlSerializer <TContext> > simplify(IReadOnlyList <IXmlSerializer <TContext> > allPossibleSerializers)
        {
            var simplifiedTypes = _typeSimplifier.Simplify(allPossibleSerializers.Select(s => s.ObjectType));

            return(from s in allPossibleSerializers
                   where simplifiedTypes.Contains(s.ObjectType)
                   select s);
        }
Exemple #2
0
        public TBuilder BuilderFor(Type type)
        {
            Start();
            if (_allBuilderCache.Contains(type))
            {
                return(_allBuilderCache[type]);
            }

            var allBuilderForType = _allBuilders.Where(b => b.IsSatisfiedBy(type)).ToList();

            //No Builder found. Return null
            if (allBuilderForType.Count == 0)
            {
                return(null);
            }

            if (allBuilderForType.Count == 1)
            {
                _allBuilderCache.Add(type, allBuilderForType[0]);
            }
            else
            {
                //more than one implementation? try to find the one that matches the best the given type
                var allGenericTypes = allBuilderForType.SelectMany(t => t.GetDeclaredTypesForGeneric(_genericBuilderType)).ToList();

                //one builder implements two ITEXBuilder<> does not make sens
                if (allGenericTypes.Count != allBuilderForType.Count)
                {
                    throw new InvalidOperationException($"Cannot resolve the Builder for type '{type}'. It seems that one builder implements more than one generic interface");
                }

                //finds the one that matches the most the implementation
                var simplifiedImplementation = _typeSimplifier.Simplify(allGenericTypes).ToList();
                if (simplifiedImplementation.Count == 1)
                {
                    _allBuilderCache.Add(type, allBuilderForType.ElementAt(allGenericTypes.IndexOf(simplifiedImplementation[0])));
                }
                else
                {
                    return(null);
                }
            }

            return(_allBuilderCache[type]);
        }
        private static Type resolveVisitorImplementationType(IList <TypeForGenericType> allPossibleImplementations, IVisitor visitor, Type typeOfObjectToVisit)
        {
            //no matching signatures, return
            if (allPossibleImplementations.Count == 0)
            {
                return(null);
            }

            //one macthing signature that the one
            if (allPossibleImplementations.Count == 1)
            {
                return(allPossibleImplementations[0].GenericType);
            }

            //can we find the implementation with our in house conventions?
            string interfaceName      = "I" + typeOfObjectToVisit.Name;
            var    typeImplementation = allPossibleImplementations.SingleOrDefault(key => key.DeclaredType.Name.Equals(interfaceName));

            if (typeImplementation != null)
            {
                return(typeImplementation.GenericType);
            }

            //at least two implementations. We now try to simplify the list of implementation to one (only one hierarchy branch)
            //if the results provide more than one type, we throw an exception

            var simplifiedImplementation = _typeSimplifier.Simplify(allPossibleImplementations).ToList();

            if (simplifiedImplementation.Count == 1)
            {
                return(simplifiedImplementation[0].GenericType);
            }

            //at least two implementations. Visit call is ambiguous and cannot be resolved at run time.
            throw new AmbiguousVisitMethodException(simplifiedImplementation, visitor.GetType(), typeOfObjectToVisit);
        }