Sdílet prostřednictvím


Definování zásady uzamčení pro vytvoření segmentů jen pro čtení

Immutability API sady Visual Studio Visualization and Modeling SDK umožňuje programu uzamknout část nebo celý model jazyka DSL (Domain-Specific Language), aby se mohl číst, ale neměnit. Tuto možnost jen pro čtení je možné použít například tak, aby uživatel mohl požádat kolegy o přidání poznámek a revizi modelu DSL, ale může jim zakázat změnu původního modelu.

Kromě toho můžete jako autor dsl definovat zásady uzamčení. Zásady uzamčení definují, které zámky jsou povolené, nepovolené nebo povinné. Když například publikujete DSL, můžete povzbuzovat vývojáře třetích stran, aby ho rozšířili o nové příkazy. Můžete ale také použít zásadu uzamčení, abyste jim zabránili ve změně stavu jen pro čtení zadaných částí modelu.

Poznámka:

Zásady uzamčení je možné obejít pomocí reflexe. Poskytuje jasnou hranici pro vývojáře třetích stran, ale neposkytuje silné zabezpečení.

Další informace a ukázky jsou k dispozici v sadě Visual Studio Visualization and Modeling SDK.

Poznámka:

Komponenta Transformace textové šablony se automaticky nainstaluje jako součást sady funkcí vývoje rozšíření sady Visual Studio. Můžete ho také nainstalovat z karty Jednotlivé komponenty Instalační program pro Visual Studio v kategorii sad SDK, knihoven a architektur. Nainstalujte komponentu Modeling SDK z karty Jednotlivé komponenty .

Nastavení a získání zámků

Zámky můžete nastavit v úložišti, v oddílu nebo u jednotlivých prvků. Tento příkaz například brání odstranění elementu modelu a také brání jeho změnám vlastností:

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

Jiné hodnoty zámku lze použít k zabránění změnám v relacích, vytváření elementů, přesunu mezi oddíly a změně pořadí odkazů v roli.

Zámky se vztahují jak na akce uživatelů, tak na programový kód. Pokud se programový kód pokusí provést změnu, vyvolá se chyba InvalidOperationException . Zámky se v operaci Zpět nebo Znovu ignorují.

Můžete zjistit, zda prvek má zámek v dané sadě pomocí a IsLocked(Locks) můžete získat aktuální sadu zámků na prvku pomocí GetLocks().

Zámek můžete nastavit bez použití transakce. Zamykací databáze není součástí úložiště. Pokud nastavíte zámek v reakci na změnu hodnoty v úložišti, například v OnValueChanged, měli byste povolit změny, které jsou součástí operace Zpět.

Tyto metody jsou rozšiřující metody definované v Microsoft.VisualStudio.Modeling.Immutability oboru názvů.

Zámky na oddílech a úložištích

Zámky lze použít také pro oddíly a úložiště. Zámek nastavený v oddílu se vztahuje na všechny prvky v oddílu. Následující příkaz například brání odstranění všech prvků v oddílu bez ohledu na stavy jejich vlastních zámků. Nicméně, další zámky, jako Locks.Property by mohly být stále nastaveny na jednotlivé prvky:

partition.SetLocks(Locks.Delete);

Zámek nastavený v úložišti se vztahuje na všechny jeho prvky bez ohledu na nastavení tohoto zámku v oddílech a prvcích.

Použití zámků

Zámky můžete použít k implementaci schémat, jako jsou například následující příklady:

  • Zakázat změny všech prvků a relací s výjimkou těch, které představují komentáře. Tento přístup umožňuje uživatelům anotovat model beze změny.

  • Zakázat změny ve výchozím oddílu, ale povolit změny v oddílu diagramu. Uživatel může změnit uspořádání diagramu, ale nemůže změnit základní model.

  • Zakázat změny úložiště s výjimkou skupiny uživatelů, kteří jsou zaregistrovaní v samostatné databázi. Pro ostatní uživatele je diagram a model jen pro čtení.

  • Zakázání změn modelu, pokud je logická vlastnost diagramu nastavena na hodnotu true. Zadejte příkaz nabídky pro změnu této vlastnosti. Tento přístup pomáhá zajistit, aby uživatelé omylem neprodávali změny.

  • Zakázání přidání a odstranění prvků a relací určitých tříd, ale povolit změny vlastností. Tento přístup uživatelům poskytuje pevný formulář, ve kterém mohou vyplnit vlastnosti.

Zamknout hodnoty

Zámky je možné nastavit v úložišti, oddílu nebo v jednotlivých modelelementech. Zámky jsou Flags výčty: jeho hodnoty můžete kombinovat pomocí |.

  • Zámky modeluElement vždy zahrnují zámky jeho oddílu.

  • Zámky oddílu vždy zahrnují zámky úložiště.

    Zámek v oddílu nebo úložišti nemůžete nastavit a zároveň zámek u jednotlivých prvků zakázat.

Hodnota Význam, pokud IsLocked(Value) je true
Nic Bez omezení.
Vlastnost Vlastnosti domény prvků nelze změnit. Tato hodnota se nevztahuje na vlastnosti, které jsou generovány rolí třídy domény v relaci.
Přidat Nové prvky a odkazy nelze vytvořit v oddílu ani úložišti. Nevztahuje se na ModelElement.
Přesunout Prvek nelze přesouvat mezi oddíly, pokud element.IsLocked(Move) je true, nebo pokud targetPartition.IsLocked(Move) je true.
Odstranění Prvek nelze odstranit, pokud je tento zámek nastaven na samotný prvek nebo u některého z prvků, do kterých by se odstranění rozšířilo, například vložené prvky a obrazce. Můžete použít element.CanDelete() ke zjištění, jestli lze prvek odstranit.
Změnit pořadí Řazení odkazů u hráče rolí se nedá změnit.
RolePlayer Sadu odkazů, které jsou zdrojové v tomto prvku, nelze změnit. Do tohoto prvku například nelze vložit nové prvky. Tato hodnota nemá vliv na odkazy, pro které je tento prvek cílem. Pokud je tento prvek odkazem, jeho zdroj a cíl nebudou ovlivněny.
Všechny Bitový operátor OR ostatních hodnot.

Uzamčení zásad

Jako autor DSL můžete definovat zásady uzamčení. Zásada uzamčení moderuje provoz SetLocks(), takže můžete zabránit nastavení konkrétních zámků nebo pověření, že konkrétní zámky musí být nastaveny. Obvykle byste použili zásadu uzamčení k tomu, abyste uživatelům nebo vývojářům zabránili v náhodném porušení zamýšleného použití DSL stejným způsobem, jakým můžete deklarovat proměnnou private.

Zásady uzamčení můžete použít také k nastavení zámků u všech prvků závislých na typu elementu. Toto chování je způsobeno SetLocks(Locks.None) tím, že je vždy volána při prvním vytvoření nebo deserializaci prvku ze souboru.

Zásady ale nemůžete použít k tomu, aby se zámky na prvku během jeho života lišily. K dosažení tohoto efektu byste měli použít volání SetLocks().

Definování zásady uzamčení:

  • Vytvořte třídu, která implementuje ILockingPolicy.

  • Přidejte tuto třídu do služeb, které jsou k dispozici prostřednictvím DocData vašeho DSL.

Definování zásad uzamčení

ILockingPolicy má následující definici:

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

Tyto metody se volají při volání v SetLocks() úložišti, oddílu nebo ModelElement. V každé metodě máte k dispozici navrženou sadu zámků. Navrženou sadu můžete vrátit nebo můžete sčítat a odečítat zámky.

Příklad:

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;
    }

Pokud chcete zajistit, aby uživatelé vždy mohli odstranit prvky, i když jiné volání kódu SetLocks(Lock.Delete):

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

Chcete-li zakázat změnu ve všech vlastnostech každého prvku MyClass:

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

Zpřístupnění zásad jako služby

DslPackage V projektu přidejte nový soubor, který obsahuje kód podobný následujícímu příkladu:

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);
    }
}