Udostępnij za pośrednictwem


Definiowanie zasad blokowania w celu utworzenia segmentów tylko do odczytu

Interfejs API niezmienności zestawu Visual Studio Visualization and Modeling SDK umożliwia programowi zablokowanie części lub wszystkich modeli języka specyficznego dla domeny (DSL, Domain-Specific Language), dzięki czemu można go odczytać, ale nie zmienić. Tej opcji tylko do odczytu można na przykład użyć, aby użytkownik mógł poprosić współpracowników o dodawanie adnotacji i przeglądanie modelu DSL, ale może uniemożliwić im zmianę oryginału.

Ponadto jako autor dsL można zdefiniować zasady blokowania. Zasady blokowania określają, które blokady są dozwolone, niedozwolone lub obowiązkowe. Na przykład podczas publikowania rozszerzenia DSL możesz zachęcić deweloperów innych firm do rozszerzenia go za pomocą nowych poleceń. Można jednak również użyć zasad blokowania, aby uniemożliwić im zmianę stanu tylko do odczytu określonych części modelu.

Uwaga

Zasady blokowania można obejść przy użyciu odbicia. Zapewnia ona wyraźną granicę dla deweloperów innych firm, ale nie zapewnia silnych zabezpieczeń.

Więcej informacji i przykładów można znaleźć w temacie Visual Studio Visualization and Modeling SDK (Visual Studio Visualization and Modeling SDK).

Uwaga

Składnik Przekształcanie szablonu tekstu jest automatycznie instalowany w ramach obciążenia programistycznego rozszerzenia programu Visual Studio. Można go również zainstalować na karcie Poszczególne składniki Instalator programu Visual Studio w kategorii Zestawy SDK, biblioteki i struktury. Zainstaluj składnik Zestawu SDK modelowania na karcie Poszczególne składniki.

Ustawianie i pobieranie blokad

Blokady można ustawić w magazynie, na partycji lub na pojedynczym elemecie. Na przykład ta instrukcja uniemożliwia usunięcie elementu modelu, a także uniemożliwia zmianę jego właściwości:

using Microsoft.VisualStudio.Modeling.Immutability; ...
element.SetLocks(Locks.Delete | Locks.Property);

Inne wartości blokady mogą służyć do zapobiegania zmianom w relacjach, tworzeniu elementów, przemieszczaniu się między partycjami i zmienianiu kolejności łączy w roli.

Blokady mają zastosowanie zarówno do akcji użytkownika, jak i do kodu programu. Jeśli kod programu próbuje wprowadzić zmianę, zostanie zgłoszony element InvalidOperationException . Blokady są ignorowane w operacji Cofnij lub Wykonaj ponownie.

Możesz dowiedzieć się, czy element ma blokadę w danym zestawie za pomocą polecenia IsLocked(Locks) i można uzyskać bieżący zestaw blokad na elemencie za pomocą polecenia GetLocks().

Blokadę można ustawić bez użycia transakcji. Baza danych blokady nie jest częścią magazynu. Jeśli ustawisz blokadę w odpowiedzi na zmianę wartości w magazynie, na przykład w OnValueChangedpliku , należy zezwolić na zmiany, które są częścią operacji Cofnij.

Metody te są metodami rozszerzeń zdefiniowanymi w Microsoft.VisualStudio.Modeling.Immutability przestrzeni nazw.

Blokady na partycjach i magazynach

Blokady można również stosować do partycji i magazynu. Blokada ustawiona na partycji ma zastosowanie do wszystkich elementów w partycji. W związku z tym na przykład poniższa instrukcja uniemożliwia usunięcie wszystkich elementów w partycji, niezależnie od stanów własnych blokad. Niemniej jednak inne blokady, takie jak Locks.Property nadal można ustawić na poszczególnych elementach:

partition.SetLocks(Locks.Delete);

Blokada ustawiona w magazynie ma zastosowanie do wszystkich elementów, niezależnie od ustawień tej blokady na partycjach i elementach.

Korzystanie z blokad

Blokady można użyć do zaimplementowania schematów, takich jak następujące przykłady:

  • Nie zezwalaj na zmiany we wszystkich elementach i relacjach z wyjątkiem tych, które reprezentują komentarze. Takie podejście umożliwia użytkownikom dodawanie adnotacji do modelu bez jego zmiany.

  • Nie zezwalaj na zmiany w partycji domyślnej, ale zezwalaj na zmiany w partycji diagramu. Użytkownik może zmienić rozmieszczenie diagramu, ale nie może zmienić bazowego modelu.

  • Nie zezwalaj na zmiany w magazynie z wyjątkiem grupy użytkowników zarejestrowanych w oddzielnej bazie danych. Dla innych użytkowników diagram i model są tylko do odczytu.

  • Nie zezwalaj na zmiany w modelu, jeśli właściwość logiczna diagramu jest ustawiona na wartość true. Podaj polecenie menu umożliwiające zmianę tej właściwości. Takie podejście pomaga zapewnić użytkownikom, że nie wprowadzają zmian przypadkowo.

  • Nie zezwalaj na dodawanie i usuwanie elementów i relacji określonych klas, ale zezwalaj na zmiany właściwości. Takie podejście zapewnia użytkownikom stały formularz, w którym mogą wypełniać właściwości.

Blokowanie wartości

Blokady można ustawić w magazynie, partycji lub poszczególnych elementach Modelu. Blokady to Flags wyliczenie: można połączyć jej wartości przy użyciu '|'.

  • Blokady elementu ModelElement zawsze zawierają blokady partycji.

  • Blokady partycji zawsze zawierają blokady magazynu.

    Nie można ustawić blokady na partycji lub magazynie i jednocześnie wyłączyć blokadę dla pojedynczego elementu.

Wartość Znaczenie, jeśli IsLocked(Value) ma wartość true
Brak Brak ograniczeń.
Właściwości Nie można zmienić właściwości domeny elementów. Ta wartość nie ma zastosowania do właściwości generowanych przez rolę klasy domeny w relacji.
Add Nie można utworzyć nowych elementów i łączy w partycji ani magazynie. Nie dotyczy .ModelElement
Przesuń Nie można przenieść elementu między partycjami, jeśli element.IsLocked(Move) ma wartość true, lub jeśli targetPartition.IsLocked(Move) ma wartość true.
Delete Nie można usunąć elementu, jeśli ta blokada jest ustawiona na samym elemecie lub na dowolnych elementach, do których będzie propagowane usunięcie, takich jak elementy osadzone i kształty. Możesz użyć element.CanDelete() polecenia , aby dowiedzieć się, czy element można usunąć.
Zmień kolejność Nie można zmienić kolejności łączy w odtwarzaczu roli.
RolePlayer Nie można zmienić zestawu łączy źródłowych w tym elemecie. Na przykład nie można osadzać nowych elementów w ramach tego elementu. Ta wartość nie ma wpływu na łącza, dla których ten element jest elementem docelowym. Jeśli ten element jest łączem, jego źródło i element docelowy nie mają wpływu.
wszystkie Bitowe OR innych wartości.

Zasady blokowania

Jako autor dsl możesz zdefiniować zasady blokowania. Zasady blokujące moderuje działanie SetLocks()elementu , dzięki czemu można zapobiec ustawianiu określonych blokad lub nakazaniu ustawiania określonych blokad. Zazwyczaj należy użyć zasad blokowania, aby zniechęcić użytkowników lub deweloperów do przypadkowego naruszenia zamierzonego użycia rozszerzenia DSL w taki sam sposób, jak można zadeklarować zmienną private.

Można również użyć zasad blokowania, aby ustawić blokady na wszystkich elementach zależnych od typu elementu. To zachowanie jest spowodowane tym, że SetLocks(Locks.None) zawsze jest wywoływana, gdy element jest tworzony po raz pierwszy lub deserializowany z pliku.

Nie można jednak używać zasad, aby zmieniać blokady elementu w jego życiu. Aby osiągnąć ten efekt, należy użyć wywołań do SetLocks().

Aby zdefiniować zasady blokowania:

  • Utwórz klasę, która implementuje ILockingPolicy.

  • Dodaj tę klasę do usług, które są dostępne za pośrednictwem danych DocData środowiska DSL.

Aby zdefiniować zasady blokowania

ILockingPolicy ma następującą definicję:

public interface ILockingPolicy
{
  Locks RefineLocks(ModelElement element, Locks proposedLocks);
  Locks RefineLocks(Partition partition, Locks proposedLocks);
  Locks RefineLocks(Store store, Locks proposedLocks);
}

Te metody są wywoływane, gdy wywołanie jest wykonywane SetLocks() w magazynie, partycji lub modeluElement. W każdej metodzie jest dostarczany proponowany zestaw blokad. Możesz zwrócić proponowany zestaw lub dodać i odjąć blokady.

Na przykład:

using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Immutability;
namespace Company.YourDsl.DslPackage // Change
{
  public class MyLockingPolicy : ILockingPolicy
  {
    /// <summary>
    /// Moderate SetLocks(this ModelElement target, Locks locks)
    /// </summary>
    /// <param name="element">target</param>
    /// <param name="proposedLocks">locks</param>
    /// <returns></returns>
    public Locks RefineLocks(ModelElement element, Locks proposedLocks)
    {
      // In my policy, users can never delete an element,
      // and other developers cannot easily change that:
      return proposedLocks | Locks.Delete);
    }
    public Locks RefineLocks(Store store, Locks proposedLocks)
    {
      // Only one user can change this model:
      return Environment.UserName == "aUser"
           ? proposedLocks : Locks.All;
    }

Aby upewnić się, że użytkownicy zawsze mogą usuwać elementy, nawet jeśli inne wywołania kodu SetLocks(Lock.Delete):

return proposedLocks & (Locks.All ^ Locks.Delete);

Aby uniemożliwić zmianę we wszystkich właściwościach każdego elementu myClass:

return element is MyClass ? (proposedLocks | Locks.Property) : proposedLocks;

Aby udostępnić zasady jako usługę

DslPackage W projekcie dodaj nowy plik zawierający kod podobny do następującego przykładu:

using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Immutability;
namespace Company.YourDsl.DslPackage // Change
{
  // Override the DocData GetService() for this DSL.
  internal partial class YourDslDocData // Change
  {
    /// <summary>
    /// Custom locking policy cache.
    /// </summary>
    private ILockingPolicy myLockingPolicy = null;

    /// <summary>
    /// Called when a service is requested.
    /// </summary>
    /// <param name="serviceType">Service requested</param>
    /// <returns>Service implementation</returns>
    public override object GetService(System.Type serviceType)
    {
      if (serviceType == typeof(SLockingPolicy)
       || serviceType == typeof(ILockingPolicy))
      {
        if (myLockingPolicy == null)
        {
          myLockingPolicy = new MyLockingPolicy();
        }
        return myLockingPolicy;
      }
      // Request is for some other service.
      return base.GetService(serviceType);
    }
}