Aracılığıyla paylaş


Salt okunur segmentler oluşturmak için kilitleme ilkesi tanımlama

Visual Studio Görselleştirme ve Modelleme SDK'sının Değiştirilemezlik API'si, bir programın okunabilmesi ancak değiştirilememesi için etki alanına özgü dil (DSL) modelinin bir bölümünü veya tamamını kilitlemesine olanak tanır. Örneğin, bu salt okunur seçenek kullanılabilir, böylece kullanıcı iş arkadaşlarınızdan DSL modeline açıklama eklemelerini ve gözden geçirmelerini isteyebilir, ancak özgün modeli değiştirmelerine izin verebilir.

Buna ek olarak, DSL'nin yazarı olarak bir kilitleme ilkesi tanımlayabilirsiniz. Kilitleme ilkesi hangi kilitlere izin verildiğini, izin verilmediğini veya zorunlu olduğunu tanımlar. Örneğin, DSL yayımladığınızda üçüncü taraf geliştiricileri yeni komutlarla genişletmeye teşvik edebilirsiniz. Ancak, modelin belirtilen bölümlerinin salt okunur durumunu değiştirmelerini önlemek için bir kilitleme ilkesi de kullanabilirsiniz.

Not

Bir kilitleme ilkesi yansıma kullanılarak aşılabilir. Üçüncü taraf geliştiriciler için net bir sınır sağlar, ancak güçlü güvenlik sağlamaz.

Visual Studio Görselleştirme ve Modelleme SDK'sı'nda daha fazla bilgi ve örnek bulabilirsiniz.

Not

Metin Şablonu Dönüştürme bileşeni, Visual Studio uzantısı geliştirme iş yükünün bir parçası olarak otomatik olarak yüklenir. Ayrıca Visual Studio Yükleyicisi Tek tek bileşenler sekmesinden SDK'lar, kitaplıklar ve çerçeveler kategorisinin altından da yükleyebilirsiniz. Tek tek bileşenler sekmesinden Modelleme SDK'sı bileşenini yükleyin.

Kilitleri ayarlama ve alma

Kilitleri depoda, bölümde veya tek bir öğede ayarlayabilirsiniz. Örneğin, bu deyim bir model öğesinin silinmesini ve ayrıca özelliklerinin değiştirilmesini engeller:

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

İlişkilerdeki değişiklikleri, öğe oluşturmayı, bölümler arasındaki hareketi ve roldeki bağlantıları yeniden sıralamayı önlemek için diğer kilit değerleri kullanılabilir.

Kilitler hem kullanıcı eylemlerine hem de program koduna uygulanır. Program kodu bir değişiklik yapmaya çalışırsa, bir InvalidOperationException oluşturulur. Geri Alma veya Yineleme işleminde kilitler yoksayılır.

kullanarak bir öğenin belirli bir kümede kilidi olup olmadığını keşfedebilir ve kullanarak IsLocked(Locks) GetLocks()bir öğedeki geçerli kilit kümesini elde edebilirsiniz.

İşlem kullanmadan kilit ayarlayabilirsiniz. Kilit veritabanı deponun bir parçası değildir. Depodaki bir değer değişikliğine yanıt olarak bir kilit ayarlarsanız ( örneğin, içinde OnValueChanged) Geri Alma işleminin parçası olan değişikliklere izin vermelisiniz.

Bu yöntemler, ad alanında Microsoft.VisualStudio.Modeling.Immutability tanımlanan uzantı yöntemleridir.

Bölümlere ve depolara kilitler

Kilitler bölümlere ve depoya da uygulanabilir. Bir bölümde ayarlanan kilit, bölümdeki tüm öğelere uygulanır. Bu nedenle, örneğin aşağıdaki deyim, kendi kilitlerinin durumlarından bağımsız olarak bir bölümdeki tüm öğelerin silinmesini engeller. Bununla birlikte, gibi Locks.Property diğer kilitler tek tek öğelerde ayarlanabilir:

partition.SetLocks(Locks.Delete);

Depoda ayarlanan bir kilit, bölümler ve öğeler üzerindeki bu kilidin ayarlarına bakılmadan tüm öğeleri için geçerlidir.

Kilitleri kullanma

Aşağıdaki örnekler gibi şemaları uygulamak için kilitleri kullanabilirsiniz:

  • Açıklamaları temsil eden öğeler dışında tüm öğelerde ve ilişkilerde değişikliklere izin verme. Bu yaklaşım, kullanıcıların modeli değiştirmeden modele açıklama eklemesine olanak tanır.

  • Varsayılan bölümdeki değişikliklere izin verme, ancak diyagram bölümünde değişikliklere izin verme. Kullanıcı diyagramı yeniden düzenleyebilir, ancak temel alınan modeli değiştiremez.

  • Ayrı bir veritabanına kayıtlı bir grup kullanıcı dışında depoda yapılan değişikliklere izin verme. Diğer kullanıcılar için diyagram ve model salt okunur durumdadır.

  • Diyagramın Boole özelliği true olarak ayarlandıysa modelde yapılan değişikliklere izin verme. Bu özelliği değiştirmek için bir menü komutu sağlayın. Bu yaklaşım, kullanıcıların yanlışlıkla değişiklik yapmamasını sağlamaya yardımcı olur.

  • Belirli sınıfların öğelerinin ve ilişkilerinin eklenmesine ve silinmesine izin verme, ancak özellik değişikliklerine izin verme. Bu yaklaşım, kullanıcılara özellikleri doldurabilecekleri sabit bir form sağlar.

Değerleri kilitleme

Kilitler bir depoda, bölümde veya tek bir ModelElement'te ayarlanabilir. Kilitler bir Flags numaralandırmadır: '|' kullanarak değerlerini birleştirebilirsiniz.

  • Bir ModelElement'in kilitleri her zaman bölümünün Kilitlerini içerir.

  • Bir bölümün kilitleri her zaman deponun Kilitlerini içerir.

    Bir bölümde veya depoda kilit ayarlayamaz ve aynı zamanda tek bir öğedeki kilidi devre dışı bırakamazsınız.

Değer Doğruysa IsLocked(Value) anlamı
Hiçbiri Kısıtlama yok.
Özellik Öğelerin etki alanı özellikleri değiştirilemez. Bu değer, bir ilişkideki etki alanı sınıfının rolü tarafından oluşturulan özellikler için geçerli değildir.
Topla Yeni öğeler ve bağlantılar bir bölümde veya depoda oluşturulamaz. için ModelElementgeçerli değildir.
Taşı Öğe doğruysa veya doğruysa element.IsLocked(Move) targetPartition.IsLocked(Move) bölümler arasında taşınamaz.
Sil Bu kilit öğenin kendisinde veya silme işleminin yayılacağı öğelerden herhangi birinde (katıştırılmış öğeler ve şekiller gibi) ayarlanırsa öğe silinemez. Bir öğenin silinip silinemeyeceğini keşfetmek için kullanabilirsiniz element.CanDelete() .
Yeniden sırala Rol oynatıcıdaki bağlantıların sırası değiştirilemez.
Roleplayer Bu öğede kaynak olarak alınan bağlantı kümesi değiştirilemez. Örneğin, yeni öğeler bu öğenin altına eklenemez. Bu değer, bu öğenin hedef olduğu bağlantıları etkilemez. Bu öğe bir bağlantıysa, kaynağı ve hedefi etkilenmez.
Tümünü Diğer değerlerin bit düzeyinde OR.

İlkeleri kilitleme

DSL'nin yazarı olarak bir kilitleme ilkesi tanımlayabilirsiniz. Bir kilitleme ilkesi, belirli kilitlerin ayarlanmasını SetLocks()önleyebilmeniz veya belirli kilitlerin ayarlanmasını zorunlu kılabilmesi için işlemini moder eder. Genellikle, kullanıcıların veya geliştiricilerin bir DSL'nin amaçlanan kullanımına yanlışlıkla karşı gelmelerini, değişken privatebildirebileceğiniz şekilde caydırmak için bir kilitleme ilkesi kullanırsınız.

Ayrıca, öğenin türüne bağlı tüm öğelerde kilitleri ayarlamak için bir kilitleme ilkesi de kullanabilirsiniz. Bu davranışın nedeni SetLocks(Locks.None) , bir öğe ilk oluşturulduğunda veya dosyadan seri durumdan çıkarıldığında her zaman çağrılır.

Ancak, bir öğenin ömrü boyunca kilitleri değiştirmek için bir ilke kullanamazsınız. Bu etkiyi elde etmek için çağrısı SetLocks()kullanmanız gerekir.

Kilitleme ilkesi tanımlamak için:

  • ILockingPolicy uygulayan bir sınıf oluşturun.

  • Bu sınıfı DSL'nizin DocData'sı aracılığıyla kullanılabilen hizmetlere ekleyin.

Kilitleme ilkesi tanımlamak için

ILockingPolicy aşağıdaki tanıma sahiptir:

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

Bu yöntemler bir depo, bölüm veya ModelElement üzerinde çağrısı yapıldığında SetLocks() çağrılır. Her yöntemde size önerilen bir kilit kümesi sağlanır. Önerilen kümeyi döndürebilir veya kilitleri ekleyip çıkarabilirsiniz.

Örneğin:

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

Diğer kod çağrıları olsa bile kullanıcıların öğeleri her zaman sileediğinden emin olmak için SetLocks(Lock.Delete):

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

MyClass'ın her öğesinin tüm özelliklerinde değişikliğe izin vermek için:

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

İlkenizi hizmet olarak kullanılabilir hale getirmek için

Projenizde DslPackage , aşağıdaki örneğe benzer kod içeren yeni bir dosya ekleyin:

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