Navigate relationships with the UML API
Note
This article applies to Visual Studio 2015. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here
A model consists of elements linked together by different kinds of relationships. This topic describes how to navigate the model in program code.
Traversing Relationships
Any relationship
Use GetRelatedElements<T>()
to find all the elements connected to a specified element. Either set T
to IRelationship
to traverse relationships of all kinds, or use a more specific type such as IAssociation
to traverse just that type.
IElement anElement;
// Select all elements related to anElement.
Context.CurrentDiagram.SelectShapes (
anElement.GetRelatedElements<IRelationship>()
.SelectMany(e=>e.Shapes()).ToArray());
Use GetRelatedLinks<T>()
to find all the relationships connected to an element.
// Process all relationships connected to an element.
foreach (IRelationship relationship in
anElement.GetRelatedLinks<IRelationship>())
{
Debug.Assert(relationship.SourceElement == anElement
|| relationship.TargetElement == anElement);
}
Association
An Association is a relationship between two Properties, each of which belongs to a Classifier.
IClassifier classifier; // class, interface, component, actor, ...
// Get all the associations sourced from this classifier
foreach (IProperty p in classifier.GetOutgoingAssociationEnds())
{
// p represents the end further end of an association.
IType oppositeElement = p.Type;
// The type to which this association connects classifier
IProperty oppositeProperty = p.Opposite;
// The nearer end of the association.
Debug.Assert(oppositeProperty.Type == classifier);
IAssociation association = p.Association;
Debug.Assert(association.MemberEnds.Contains(p)
&& association.MemberEnds.Contains(oppositeProperty));
}
Generalization and Realization
Access opposite ends of generalization:
foreach (IClassifier supertype in classifier.Generals) {…}
foreach (IClassifier subtype in classifier.GetSpecifics()) {…}
Access the relationship itself:
foreach (IGeneralization gen in classifier.Generalizations)
{ Debug.Assert(classifier == gen.Specific); }
/// InterfaceRealization:
IEnumerable<IInterface> GetRealizedInterfaces
(this IBehavioredClassifier classifier);
IEnumerable<IBehavioredClassifier> GetRealizingClassifiers
(this IInterface interface);
Dependency
/// Returns the elements depending on this element
IEnumerable<INamedElement> GetDependencyClients(this INamedElement element);
/// Returns the elements this element depends on
IEnumerable<INamedElement> INamedElement GetDependencySuppliers(this INamedElement element);
Activity Edge
/// Returns the nodes targeted by edges outgoing from this one
IEnumerable<IActivityNode> GetActivityEdgeTargets(this IActivityNode node);
/// Returns the nodes sourcing edges incoming to this one
IEnumerable<IActivityNode> GetActivityEdgeSources(this IActivityNode node);
Connector (assembly and delegation)
/// Returns the elements connected via assembly
/// or delegation to this one
IEnumerable<IConnectableElement> GetConnectedElements(this IConnectableElement element);
Messages and Lifelines
IEnumerable<IMessage> GetAllOutgoingMessages(this ILifeline lifeline);
// both from lifeline and execution occurrences
IEnumerable<IMessage> GetAllIncomingMessages(this ILifeline lifeline);
ILifeline GetSourceLifeline(this IMessage message);
// may return null for found messages
ILifeline GetTargetLifeline(this IMessage message);
// may return null for lost messages
Package Import
IEnumerable<IPackage>GetImportedPackages(this INamespace namespace);
IEnumerable<INamespace> GetImportingNamespaces(this IPackage package);
Use case extend and include
IEnumerable<IUseCase>GetExtendedCases(this IUseCase usecase);
IEnumerable<IUseCase>GetExtendingCases(this IUseCase usecase);
IEnumerable<IUseCase>GetIncludedCases(this IUseCase usecase);
IEnumerable<IUseCase>GetIncludingCases(this IUseCase usecase);
Enumerating Relationships
All properties of the UML model that return multiple values conform to the IEnumerable<> interface. This means that you can use Linq Query Expressions and the extension methods defined in the System.Linq namespace.
For example:
from shape in Context.CurrentDiagram.GetSelectedShapes<IClassifier>()
where shape.Color == System.Drawing.Color.Red
select shape.Element