Пример #1
0
        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);
        }
Пример #2
0
 public CastEdge(TypeVertex castFrom, TypeVertex castTo)
 {
     CastFrom = castFrom;
     CastTo   = castTo;
 }
Пример #3
0
 public bool PathExists(TypeVertex from, TypeVertex to)
 {
     return(!_transitiveClosure[from.Index][to.Index].IsEmpty());
 }
Пример #4
0
 public PropertyEdge(TypeVertex parent, PropertyInfo property, TypeVertex child)
 {
     Parent       = parent;
     PropertyInfo = property;
     Child        = child;
 }