كيفية القيام بما يلي: قم بتحرير "الرسومات التخطيطية للتسلسل" استخدام API ل UML

التفاعل هو سلسلة من الرسائل بين مجموعة من فترات التواجد. يتم عرض التفاعل على مخطط تسلسل.

للتفاصيل الكاملة للـ API, راجع Microsoft.VisualStudio.Uml.Interactions.

للحصول على مقدمة أكثر عمومية حول كتابة الأوامر و معالجات الإيماءات لمخططات UML ، راجع كيفية القيام بما يلي: تعريف أمر قائمة على مخطط طراز.

التعليمات البرمجية الأساسية

استيراد مساحة الاسم

يجب عليك تضمين عبارات using التالية:

using Microsoft.VisualStudio.Uml.Classes;
   // for basic UML types such as IPackage
using Microsoft.VisualStudio.Uml.Interactions;
   // for interaction types
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
   // to create elements and use additional functions

إذا كنت تقوم بإنشاء أوامر قائمة و معالجات الإيماءات, ستحتاج أيضاً إلى:

using System.ComponentModel.Composition; 
   // for Import and Export
using Microsoft.VisualStudio.Modeling.ExtensionEnablement;
   // for ICommandExtension
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
   // for diagrams and context

لمزيد من المعلومات، راجع كيفية القيام بما يلي: تعريف أمر قائمة على مخطط طراز.

الحصول على السياق

إذا كنت تقوم بتحرير تفاعل كجزء من الأمر أو معالج الإيماءة في مخطط تسلسل, يمكنك الحصول على مرجع إلى السياق. فعلى سبيل المثال:

    [SequenceDesignerExtension]
    [Export(typeof(ICommandExtension))]  
    public class MySequenceDiagramCommand : ICommandExtension
    {
        [Import]
        public IDiagramContext Context { get; set; }
        public void QueryStatus (IMenuCommand command)
        {
          ISequenceDiagram sequenceDiagram = 
              Context.CurrentDiagram as ISequenceDiagram;
             ...

مخططات تسلسل منشأة و UML

هناك نوعان من مخططات التسلسل: تلك التي يتم إنشاؤها يدوياً في مشروع طراز UML ، وتلك التي تم إنشاؤها من التعليمات البرمجية للبرنامج. يمكنك استخدام الخاصية UmlMode لاكتشاف أي نوع من مخططات التسلسل تعمل بها.

على سبيل المثال، إذا كنت تريد تصنع أمر قائمة فقط يكون مرئياً فقط في مخططات تسلسل UML, فالأسلوب QueryStatus() قد يتضمّن العبارة التالية:

    command.Enabled = command.Visible = 
          sequenceDiagram != null && sequenceDiagram.UmlMode;

في مخطط تسلسل تم إنشاؤه ، فترات التواجد و الرسائل والعناصر الأخرى تشبه كثيرا تلك التي في مخطط تسلسل UML . في طراز UML, لدى "مخزن طراز" جذر و هو "الطراز" الذي يملك كافة العناصر الأخرى; لكن التفاعل الذي تم إنشاؤه يوجد في مخزن الطراز الخاص به والذي لديه جذر خالي:

    IModel rootModel = sequenceDiagram.ModelStore.Root;
    // !sequenceDiagram.UmlMode == (rootModel == null)

لإنشاء و عرض تفاعل

أنشئ التفاعل كتابع لحزمة أو لطراز.

على سبيل المثال، إذا كنت تقوم بتطوير أمر قد يتم تنفيذه على مخطط تسلسل فارغ ، يجب أن تبدأ دائماً عن طريق التحقق من وجود التفاعل.

public void Execute (IMenuCommand command)
{
    ISequenceDiagram sequenceDiagram = 
         Context.CurrentDiagram as ISequenceDiagram;
    if (sequenceDiagram == null) return;
    // Get the diagram's interaction:
    IInteraction interaction = sequenceDiagram.Interaction;
    // A new sequence diagram might have no interaction:
    if (interaction == null)
    {
       // Get the home package or model of the diagram:
       IPackage parentPackage = sequenceDiagram.GetObject<IPackage>();
       interaction = parentPackage.CreateInteraction();
       // Display the interaction on the sequence diagram:
       sequenceDiagram.Bind(interaction);
    } 

تحديث تفاعل و التخطيط الخاص به

عند تحديث تفاعل, يجب عليك دائماً إنهاء العملية عن طريق تحديث التخطيط الخاص بها باستخدام أحد الأساليب التالية:

  • ISequenceDiagram.UpdateShapePositions() يضبط المواضع الخاصة بالأشكال التي تم مؤخراً إدراجها أو نقلها، و الأشكال المجاورة لها.

  • ISequenceDiagram.Layout([SequenceDiagramLayoutKinds]) يعيد رسم المخطط بالكامل. يمكنك استخدام المعامل لتحديد إعادة تعيين مواضع فترات التواجد أو الرسائل أو كليهما.

هذا مهم بشكل خاص عند إدراج عناصر جديدة أو نقل عناصر موجودة. لن يكونوا في المواضع الصحيحة على المخطط حتى تقوم بإجراء إحدى هذه العمليات. تحتاج فقط لاستدعاء إحدى هذه العمليات مرة واحدة في نهاية سلسلة من التغييرات.

لتتجنب إرباك المستخدم الذي يقوم بإجراء تراجع بعد الأمر ، استخدام ILinkedUndoTransaction لإحاطة التغييرات الخاصة بك و Layout() النهائية أو عمليات UpdateShapePositions() . فعلى سبيل المثال:

using (ILinkedUndoTransaction transaction = LinkedUndoContext.BeginTransaction("create loop"))
{
  Interaction.CreateCombinedFragment(InteractionOperatorKind.Loop, messages);
  Diagram.UpdateShapePositions();
  transaction.Commit();
}

لتستخدم ILinkedUndoTransaction ، يجب عليك أن تجعل هذا التعريف في الفئة الخاصة بها:

[Import] ILinkedUndoContext LinkedUndoContext { get; set; }

لمزيد من المعلومات، راجع كيفية القيام بما يلي: ربط تحديثات طراز باستخدام العمليات.

إنشاء تفاعل

لإنشاء فترات تواجد

ILifeline lifeline = interaction.CreateLifeline();

فترة التواجد تمثّل عنصر قابل للتوصيل ، أي مثيل من نوع. على سبيل المثال، إذا تم استخدام التفاعل لإظهار كيفية تفويض مكون للرسائل الواردة لأجزائه الداخلية, فترات التواجد يمكنها أن تمثّل منافذ و أجزاء المكون:

foreach (IConnectableElement part in 
            component.Parts
           .Concat<IConnectableElement>(component.OwnedPorts))
{
   ILifeline lifeline = interaction.CreateLifeline();
   lifeline.Represents = part;
}

بدلاً من ذلك، إذا كان التفاعل يعرض مجموعة إجبارية من الكائنات، يمكنك إنشاء خاصية أو IConnectableElement آخر في التفاعل نفسه:

ILifeline lifeline = interaction.CreateLifeline();
IProperty property1 = interaction.CreateProperty();
property1.Type = model.CreateInterface();
property1.Type.Name = "Type 1";
lifeline.Represents = property1;

كبديل آخر، يمكن تعيين اسم ونوع فترة التواجد دون ربطه بعنصر قابل للتوصيل:

ILifeline lifeline = interaction.CreateLifeline();
lifeline.Name = "c1";
lifeline.SetInstanceType("Customer");
System.Diagnostics.Debug.Assert(
           lifeline.GetDisplayName() == "c1:Customer"  );

لإنشاء رسائل

لإنشاء رسالة ، يجب عليك تحديد نقاط الإدراج على فترات التواجد المصدر و الهدف. فعلى سبيل المثال:

interaction.CreateMessage( sourceInsertionPoint, 
                           targetInsertionPoint, 
                           MessageKind.Complete, 
                           MessageSort.ASynchCall)

لإنشاء رسالة تحتوي على مصدر غير معرّف أو هدف غير معرّف:

interaction.CreateLostFoundMessage(MessageKind.Found, insertionPoint);

هناك عدة رسائل يمكنك استخدامها لتحديد نقاط الإدراج عند كل النقاط الأساسية على فترة تواجد:

أسلوب على ILifeline

استخدم ذلك للإدراج عند هذه النقطة

FindInsertionPointAtTop()

الجزء العلوي من فترة التواجد.

FindInsertionPointAtBottom()

الجزء السفلي من فترة التواجد.

FindInsertionPointAfterMessage

(IMessage previous)

نقطة موجودة مباشرة بعد الرسالة المحددة.

FindInsertionPointAfterExecutionSpecification

(IExecutionSpecification previous)

النقطة يمكن أن تكون إما على فترة التواجد, أو على كتلة مواصفات تنفيذ أصلية.

FindInsertionPointAfterInteractionUse

(IInteractionUse previous)

نقطة تالية لـ"استخدام تفاعل".

FindInsertionPointAfterCombinedFragment

(ICombinedFragment previous)

نقطة تالية لـ"جزء مدمج".

FindInsertionPoint(IExecutionSpecification block)

الجزء العلوي من كتلة تنفيذ.

FindInsertionPoint(IInteractionOperand fragment)

الجزء العلوي من مُعامل جزء مدمج.

عند إنشاء رسائل, تجنَّب تعريف رسالة قد تتقاطع مع رسالة أخرى.

لإنشاء أجزاء مدمجة و استخدامات تفاعل

يمكنك إنشاء أجزاء مدمجة و استخدامات تفاعل بواسطة تحديد نقطة إدراج على كل فترة تواجد يجب أن يتم تغطيتها بواسطة العنصر. تجنب تحديد مجموعة من النقاط التي قد تتقاطع مع جزء أو رسالة موجودة.

Interaction.CreateCombinedFragment(InteractionOperatorKind.Loop, 
  Interaction.Lifelines.Select(lifeline => lifeline.FindInsertionPointAtTop()));
Interaction.CreateInteractionUse(
  Interaction.Lifelines.Select(lifeline => lifeline.FindInsertionPointAtTop()));

يمكنك أيضاً إنشاء جزء مدمج يغطّي مجموعة موجودة من الرسائل. الرسائل يجب أن تكون كلها محددة المصدر في نفس فترة التواجد أو كتلة التنفيذ.

ICombinedFragment cf = Interaction.CreateCombinedFragment(
  InteractionOperatorKind.Loop,
  Interaction.Lifelines.First().GetAllOutgoingMessages());

يتم إنشاء الجزء المدمج دوماً بمعامل مفرد. لإنشاء معامل جديد, يجب عليك تحديد المعامل الموجود الذي تريد إدراجه قبل أو بعد, و ما إذا كنت تريد إدراجه بعده أو قبله:

// Create an additional operand before the first
cf.CreateInteractionOperand(cf.Operands.First(), false);
// Create an additional operand after the last:
cf.CreateInteractionOperand(cf.Operands.Last(), true);

استكشاف الأخطاء وإصلاحها

تظهر الأشكال في مواضع غير صحيحة إذا لم يتم إكمال التغييرات بمعامل UpdateShapePositions() أو Layout() .

معظم المشاكل الأخرى تنتج عن نقاط إدراج يتم محاذاتها بطريقة خاطئة ، بحيث أن الرسائل أو الأجزاء الجديدة تتقاطع مع الآخرين. الأعراض قد تكون عدم حدوث تغيير , أو ظهور استثناء. قد لا يتم طرح الاستثناء حتى يتم تنفيذ العملية UpdateShapePositions() أو Layout() .

راجع أيضًا:

المرجع

Microsoft.VisualStudio.Uml.Interactions

موارد أخرى

طرازات متوسعه و مخططات

كيفية القيام بما يلي: تعريف أمر قائمة على مخطط طراز

كيفية القيام بما يلي: تعريف عنصر مربع أدوات طراز مخصص

كيفية القيام بما يلي: تعريف قيود التحقق من صحة طرازات UML

برمجة بإستخدام API UML