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); }
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); }