private static bool CanAddRelation(UmlDiagram diagram, PropertyUmlMember prop) { var reflectedType = prop.Property.ReflectedType; var interfaces = reflectedType.GetInterfaces(); var propertyName = prop.Property.Name; if (reflectedType.IsInterface) { return(true); } foreach (var intf in interfaces) { if (diagram.ContainsType(intf)) { // var map = reflectedType.GetInterfaceMap(intf); foreach (var i in map.TargetMethods) { if (!IsPropertyMethod(i, propertyName)) { continue; } // don't add relation if there is interface on the diagrarm with same relation if (prop.Property.GetMethod == i || prop.Property.SetMethod == i) { return(false); } } } } var declaringType = prop.Property.DeclaringType; if (reflectedType != declaringType) { var tt = reflectedType.BaseType; while (tt != null) { if (diagram.ContainsType(tt)) { return(false); } if (tt == declaringType) { break; } tt = tt.BaseType; } } return(true); }
private IEnumerable <Type> ProcessProperty(UmlDiagram diagram, UmlEntity diagClass, PropertyUmlMember property) { var decision = ConvertToRelation?.Invoke(property) ?? ChangeDecision.Auto; if (decision == ChangeDecision.Auto) { if (property.Property.GetCustomAttribute <DontConvertToRelationAttribute>() != null) { decision = ChangeDecision.No; } else { decision = ChangeDecision.Yes; } } if (decision == ChangeDecision.No) { yield break; } if (diagClass.Type != property.Property.DeclaringType) { if (diagram.ContainsType(diagClass.Type.BaseType)) { property.HideOnList = true; yield break; } } var doNotResolveCollections = property.Property.GetCustomAttribute <BaseRelationAttribute>()?.DoNotResolveCollections ?? false; var ti = new TypeExInfo(property.Property.PropertyType, doNotResolveCollections); if (!diagram.ContainsType(ti.ElementType)) { yield break; } // create relation if (!CanAddRelation(diagram, property)) { yield break; } property.HideOnList = true; var arrow = new UmlRelationArrow( ArrowEnd.Empty, ti.IsCollection ? ArrowEnd.Multiple : ArrowEnd.ArrowOpen); var owner = diagClass.Type; var arrowTargetType = ti.ElementType; const string ownerLabel = ""; const string componentLabel = ""; var att = property.Property.GetCustomAttribute <UmlRelationAttribute>(); if (att != null) { var relationTi = new TypeExInfo(att.RelatedType ?? property.Property.PropertyType, att.DoNotResolveCollections); arrow = UmlRelationArrow.MkArrow(att, GetMultiplicity(att.Multiple, relationTi.IsCollection)); if (att.ForceAddToDiagram) { yield return(relationTi.ElementType); } arrowTargetType = relationTi.ElementType; } var rel = new UmlRelation { Left = new UmlRelationEnd(diagram.GetTypeName(owner), ownerLabel), Right = new UmlRelationEnd(diagram.GetTypeName(arrowTargetType), componentLabel), Arrow = arrow, Label = string.IsNullOrEmpty(att?.Name) ? property.Name : att.Name } .WithNote(att) .WitCreatorMeta <MemberToRelationVisitor>(owner, arrowTargetType); rel.Tag = att?.Tag; rel.BaseMember = property; { var eventHandler = AfterConversionProperty; if (eventHandler != null) { var args = new AfterConversionPropertyEventArgs { Diagram = diagram, Entity = diagClass, BaseUmlMember = property, Relation = rel }; eventHandler(this, args); } } diagram.Relations.Add(rel); }