public TypeGraph(IEnumerable <Type> types) { var interfaces = SearchHelper <TBaseSearchInterface> .GetAllSearchInterfaces(types).ToList(); Vertices = new TypeVertex[interfaces.Count]; var counter = 0; foreach (var intType in interfaces) { TypeVertex vertex; if (!_searchVertices.TryGetValue(intType, out vertex)) { vertex = _searchVertices[intType] = new TypeVertex(intType, counter++); Vertices[vertex.Index] = vertex; } var castTypes = SearchHelper <TBaseSearchInterface> .FindBase(intType) .Concat(SearchHelper <TBaseSearchInterface> .FindDerived(intType)); foreach (var castType in castTypes) { TypeVertex childVertex; if (!_searchVertices.TryGetValue(castType, out childVertex)) { childVertex = _searchVertices[castType] = new TypeVertex(castType, counter++); Vertices[childVertex.Index] = childVertex; } vertex.Casts.AddLast(new CastEdge(vertex, childVertex)); } var propertyInfos = intType.GetProperties().Where(p => p.GetCustomAttribute <SearchContainerAttribute>() != null); foreach (var info in propertyInfos) { var propertyType = CollectionUtils.GetElementType(info.PropertyType); if (!typeof(TBaseSearchInterface).IsAssignableFrom(propertyType)) { throw new InvalidCastException("Все должно наследоваться от базового интерфейса"); } if (!propertyType.IsInterface) { throw new InvalidOperationException("Все свойства интерфейсы"); } if (propertyType.IsGenericType) { throw new NotSupportedException("Generics are not supported"); } _allPropertyInfos.Add(info); TypeVertex childVertex; if (!_searchVertices.TryGetValue(propertyType, out childVertex)) { childVertex = _searchVertices[propertyType] = new TypeVertex(propertyType, counter++); Vertices[childVertex.Index] = childVertex; } var edge = new PropertyEdge(vertex, info, childVertex); vertex.Children.AddLast(edge); childVertex.Parents.AddLast(edge); } } if (counter != interfaces.Count) { throw new Exception("Количество интерфейсов не соответствует графу"); } _transitiveClosure = BuildAdjacencyMatrix(); FillTransitiveClosure(_transitiveClosure); }
public CastEdge(TypeVertex castFrom, TypeVertex castTo) { CastFrom = castFrom; CastTo = castTo; }
public bool PathExists(TypeVertex from, TypeVertex to) { return(!_transitiveClosure[from.Index][to.Index].IsEmpty()); }
public PropertyEdge(TypeVertex parent, PropertyInfo property, TypeVertex child) { Parent = parent; PropertyInfo = property; Child = child; }