Nasıl yapılır: UML Modelleri için Doğrulama Kısıtlamaları Tanımlama
Visual Studio Ultimate öğesinde, modelin belirttiğiniz koşulu karşılayıp karşılamadığını test eden doğrulama kısıtlamalarını tanımlayabilirsiniz.Örneğin, kullanıcının kalıtım ilişkileri döngüsünü oluşturmadığından emin olmak için bir kısıtlama tanımlayabilirsiniz.Kısıtlama, kullanıcı modeli açmaya veya kaydetmeye çalıştığı zaman çağrılır ve ayrıca el ile çağrılabilir.Eğer kısıtlama başarısız olursa, tanımladığınız bir hata iletisi hata penceresine eklenir.Bu kısıtlamaları bir Visual Studio Tümleştirme Uzantısı (VSIX) içine paketleyebilir ve diğer Visual Studio Ultimate kullanıcılarına dağıtabilirsiniz.
Ayrıca, modeli veritabanları gibi dış kaynaklara karşı da doğrulayan kısıtlamalar tanımlayabilirsiniz.
[!NOT]
Program kodunu katman diyagramına karşı doğrulamak istiyorsanız, bkz.: Katman Diyagramlarına Özel Mimari Doğrulaması Ekleme.
Gereksinimler
Visual Studio Galerisi adresinden edinebileceğiniz Visual Studio SDK.
Kod Galerisindeki Visual Studio Görselleştirme ve Modelleme SDK'si adresinden edinebileceğiniz Visual Studio Görselleştirme ve Modelleme SDK'si.
Doğrulama Kısıtlamalarını Uygulama
Doğrulama kısıtlamaları üç durumda uygulanır: Bir modeli kaydettiğinizde; bir modeli açtığınızda ve Mimari menüsündeki UML Modeli Doğrula'yı tıklattığınızda.Her durumda, genellikle her kısıtlamayı birden çok duruma uygulamak için tanımlamanıza rağmen sadece o durum için tanımlanmış kısıtlamalar uygulanacaktır.
Doğrulama hataları Visual Studio hataları penceresinde bildirilir ve hatalı model öğelerini seçmek için hataya çift tıklayabilirsiniz.
Doğrulamayı uygulama hakkında daha fazla bilgi için bkz. UML Modelini Doğrulama.
Geçerlilik Uzatma Tanımlama
Bir UML tasarımcısı için bir doğrulama uzantısı oluşturmak üzere doğrulama sınırlamalarının davranışını belirleyen bir sınıf oluşturmanız ve sınıfı bir Visual Studio Tümleştirme Uzantısı'na (VSIX) katıştırmanız gerekir.VSIX kısıtlamayı yükleyebilecek bir kapsayıcı gibi davranır.Bir doğrulama uzantısı tanımlamanın iki farklı yöntemi var:
Proje şablonunu kullanarak kendi VSIX paketi içerisinde bir doğrulama uzantısı oluşturun. Bu daha hızlı yöntemdir.Doğrulama sınırlamalarınızı menü komutları, özel araç kutusu öğeleri veya hareket işleyicileri gibi diğer tür uzantılarla birleştirmek istemiyorsanız, bunu kullanın.Tek bir sınıfta çeşitli kısıtlamalar tanımlayabilirsiniz.
Ayrı doğrulama sınıfı ve VSIX projeleri oluşturun. Aynı VSIX içinde bir kaç tür uzantıyı birleştirmek istiyorsanız bu yöntemi kullanın.Örneğin, menü komutunuz modelin belirli kısıtlamalar ortaya koyacağını ön görüyorsa bunu bir doğrulama yöntemi olarak aynı VSIX içine katıştırabilirsiniz.
Kendi VSIX'inde bir doğrulama uzantısı oluşturmak için
Yeni proje iletişim kutusunda, Modelleme Projeleri'nin altında, Doğrulama Uzantısı'na tıklayın.
Yeni projede .cs dosyasını açın ve doğrulama kısıtlamanızı uygulamak için sınıfı değiştirin.
Daha fazla bilgi için bkz. Doğrulama Kısıtlamasını Uygulama.
Önemli .cs dosyalarınızda aşağıdaki using deyiminin bulunduğundan emin olun:
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
Yeni yöntemler tanımlayarak ek sınırlamalar ekleyebilirsiniz.Bir yöntemi doğrulama yöntemi olarak tanımlamak için yöntem aynı ilk doğrulama yönteminde olduğu gibi özniteliklerle etiketlenmiş olmalıdır.
F5 tuşuna basarak kısıtlamaları test edin.Daha fazla bilgi için bkz. Doğrulamayı Yürütme.
Menü komutunu projeniz tarafından oluşturulan bin\*\*.vsix dosyasını kopyalayarak başka bir bilgisayara yükleyin.Daha fazla bilgi için bkz. Doğrulama Kısıtlamalarını Yükleme.
Diğer .cs dosyalarını eklediğinizde, genellikle aşağıdaki using ifadeler gerekecektir:
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
using Microsoft.VisualStudio.Modeling.Validation;
using Microsoft.VisualStudio.Uml.Classes;
Alternatif yordam şöyledir:
Bir sınıf kitaplığı projesinde ayrı bir doğrulama kısıtlaması oluşturmak için
Bir sınıf kitaplığı projesini varolan bir VSIX çözümüne ekleyerek veya yeni bir çözüm oluşturarak oluşturun.
Dosya menüsünde Yeni, Proje seçeneğini belirleyin.
Yüklü Şablonlar altında Visual C# veya Visual Basic'i açın, ardından orta sütundaki Sınıf Kitaplığı'nı seçin.
Çözümünüz bir tane içermiyorsa, bir VSIX projesi oluşturun:
Çözüm Gezgini'nde, çözümün kısayol menüsünde, Ekle'yi ve Yeni Proje'yi seçin.
Yüklü Şablonlar altından Visual C# veya Visual Basic'i genişletin ardından Genişletilebilirlik'i seçin.Orta sütundaki VSIX Projesi'ni seçin.
Çözümün başlangıç projesi olarak VSIX projesini ayarlayın.
- Çözüm Gezgini'nde VSIX projesinin kısayol menüsünde Başlangıç Projesi Olarak Ayarla'yı seçin.
source.extension.vsixmanifest öğesinde, İçerik'in altında, sınıf kitaplığı projesini MEF Bileşeni olarak ekleyin:
Meta Veriler sekmesinde, VSIX için bir ad ayarlayın.
Hedefleri Yükle sekmesinde, hedefler olarak Visual Studio Ultimate ve Premium ayarlayın.
Varlıklar sekmesinde, bir Yeni seçin ve iletişim kutusunda şunu ayarlayın:
Tür = MEF Bileşeni
Kaynak = Mevcut çözümde bir proje
Proje = Your class library project
Doğrulama Sınıfını tanımlamak için
Kendi VSIX doğrulama proje şablonu olan bir doğrulama sınıfı oluşturduysanız, bu yordama ihtiyacınız yoktur.
Doğrulama sınıfı projesinde, aşağıdaki .NET derlemelerine başvurular ekleyin:
Microsoft.VisualStudio.Modeling.Sdk.12.0
Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml
Microsoft.VisualStudio.Uml.Interfaces
System.ComponentModel.Composition
Aşağıdaki örneğe benzer bir kod içeren sınıf kitaplığı projesine bir dosya ekleyin.
Her doğrulama kısıtlaması belirli bir öznitelikle işaretlenmiş bir yöntem içerisinde yer alır.Yöntem, bir model öğe türünün parametresini kabul eder.Doğrulama çağrıldığında doğrulama framework'ü her doğrulama yöntemini, parametre türüne uyan her model öğe üzerinde uygulayacaktır.
Bu yöntemleri tüm sınıflara ve ad alanlarına yerleştirebilirsiniz.Bunları tercihinize uygun olarak değiştirin.
using System.Collections.Generic; using System.ComponentModel.Composition; using System.Linq; using Microsoft.VisualStudio.Modeling.Validation; using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml; using Microsoft.VisualStudio.Uml.Classes; // You might also need the other Microsoft.VisualStudio.Uml namespaces. namespace Validation { public class MyValidationExtensions { // SAMPLE VALIDATION METHOD. // All validation methods have the following attributes. [Export(typeof(System.Action<ValidationContext, object>))] [ValidationMethod( ValidationCategories.Save | ValidationCategories.Open | ValidationCategories.Menu)] public void ValidateClassNames (ValidationContext context, // This type determines what elements // will be validated by this method: IClass elementToValidate) { // A validation method should not change the model. List<string> attributeNames = new List<string>(); foreach (IProperty attribute in elementToValidate.OwnedAttributes) { string name = attribute.Name; if (!string.IsNullOrEmpty(name) && attributeNames.Contains(name)) { context.LogError( string.Format("Duplicate attribute name '{0}' in class {1}", name, elementToValidate.Name), "001", elementToValidate); } attributeNames.Add(name); } } // Add more validation methods for different element types. } }
Doğrulama Kısıtlaması Yürütme
Test amaçları için doğrulama yöntemlerinizi hata ayıklama modunda yürütün.
Doğrulama sınırlamasını test etmek için
F5 tuşuna basın veya Hata Ayıklayıcı menüsünde Hata Ayıklama Başlat öğesini seçin.
Visual Studio deneysel örneği başlar.
Sorun giderme: Yeni bir Visual Studio başlamazsa:
Birden fazla projeniz varsa, VSIX projesinin çözümün Başlangıç projesi olarak ayarlandığından emin olun.
Çözüm Gezgini'nde başlatmanın veya yalnızca projenin kısayol menüsünde Özellikler'i seçin.Proje özellikleri düzenleyicisinden Hata Ayıklama sekmesini belirtin.Harici program başlat alanındaki dizenin tipik olarak Visual Studio öğesinin tam yol adı olduğunu doğrulayın:
C:\Program Files\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe
Deneysel Visual Studio üzerinde bir modelleme projesi oluşturun veya açın ve bir modelleme diyagramı oluşturun veya açın.
Önceki bölümde verilen örnek kısıtlama için bir test kurmak:
Sınıf diyagramı açın.
Bir sınıf oluşturun ve aynı adı taşıyan iki öznitelik ekleyin.
Diyagramın herhangi bir yerinde, kısayol menüsünde Doğrula'yı seçin.
Modeldeki herhangi bir hata, hata penceresinde bildirilecektir.
Hata raporuna çift tıklayın.Raporda belirtilen öğeler ekranda görünür durumdaysa vurgulanacaklardır.
Sorun giderme: Doğrula komutu menüde görünmüyorsa, şundan emin olun:
Doğrulama projesi VSIX projesinde source.extensions.manifest öğesindeki Varlıklar sekmesinde bir MEF bileşeni olarak listelenir.
Doğru Export ve ValidationMethod öznitelikleri doğrulama yöntemlerine eklenir.
ValidationCategories.Menu, ValidationMethod özniteliği için bağımsız değişkene eklenmiştir ve Mantıksal OR (|) kullanan diğer değerlerle oluşturulmuştur.
Tüm Import ve Export özniteliklerinin parametreleri geçerlidir.
Kısıtlamayı Değerlendirme
Doğrulama yöntemi, uygulamak istediğiniz doğrulama kısıtlamasının doğru veya yanlış olup olmadığını denetlemelidir.Doğru ise, doğrulama yöntemi hiçbir şey yapmamalı.Yanlış ise, ValidationContext parametreleri tarafından sağlanan yöntemleri kullanarak hatayı bildirmelidir.
[!NOT]
Doğrulama yöntemlerinin modeli değiştirmemesi gerekir.Kısıtlamaların ne zaman veya ne sırada yürütüleceğinin garantisi yoktur.Doğrulama çalışması içinde doğrulama yönteminin birbirini izleyen yürütmeleri arasında bilgi geçirmek zorundaysanız, Birden Çok Doğrulamayı Düzenleme'nin altında açıklanan bağlam önbelleğini kullanabilirsiniz.
Örneğin, her türün (sınıf, arayüz, sabit listesi) en az üç karakter uzunluğunda olduğundan emin olmak istiyorsanız, bu yöntemi kullanabilirsiniz:
public void ValidateTypeName(ValidationContext context, IType type)
{
if (!string.IsNullOrEmpty(type.Name) && type.Name.Length < 3)
{
context.LogError(
string.Format("Type name {0} is too short", type.Name),
"001", type);
}
}
Modelde gezinmek ve modeli okumak için kullanabileceğiniz yöntem ve türler hakkında bilgi edinmek için bkz. UML API ile Programlama
Kısıtlama Yöntemlerini Doğrulama Hakkında
Her doğrulama kısıtlaması aşağıdaki formdaki bir yöntem tarafından tanımlanır:
[Export(typeof(System.Action<ValidationContext, object>))]
[ValidationMethod(ValidationCategories.Save
| ValidationCategories.Menu
| ValidationCategories.Open)]
public void ValidateSomething
(ValidationContext context, IClassifier elementToValidate)
{...}
Öznitelikler ve her doğrulama yönteminin parametreleri aşağıdaki gibidir:
[Export(typeof(System.Action <ValidationContext, object>))] |
Yöntemi Yönetilen Genişletilebilirlik Çerçevesi (MEF) kullanarak doğrulama kısıtlaması olarak tanımlar. |
[ValidationMethod (ValidationCategories.Menu)] |
Doğrulamanın gerçekleşeceği zamanı belirtir.Birden fazla seçeneği birleştirmek istiyorsanız bit düzey VEYA'yı (|) kullanın. Menu = Doğrulama menüsü tarafından çağrılır. Save = modeli kaydederken çağrılır. Open = modeli açarken çağrılır.Load = modeli kaydederken, ancak ihlalin modeli tekrar açmanın mümkün olamayabileceği hakkında kullanıcıyı uyarması için çağrılır.Model ayrıştırılmadan önce yüklemede de çağrılır. |
public void ValidateSomething (ValidationContext context, IElement element) |
İkinci parametre olan IElement parametresini kısıtlamanın uygulamasını istediğiniz türdeki öğe tarafından değiştirin.Kısıtlama yöntemi belirtilen türdeki tüm öğelere çağrılacaktır. Yöntemin adı önemli değildir. |
İkinci parametrede farklı türler ile istediğiniz sayıda doğrulama yöntemi tanımlayabilirsiniz.Doğrulama çağrıldığında her doğrulama yöntemi, parametre türüne uyan her model öğe üzerinde çağrılacaktır.
Doğrulama Hatalarını Raporlama
Bir hata raporu oluşturmak için ValidationContext tarafından sağlanan yöntemleri kullanın:
context.LogError("error string", errorCode, elementsWithError);
"error string", Visual Studio Hata Listesi'nde görünüyor.
errorCode hatanın benzersiz tanımlayıcısı olması gereken dizedir
elementsWithError modeldeki öğeleri tanımlar.Kullanıcı hata raporuna çift tıkladığında, bu öğeyi gösteren şekil seçilecektir.
LogError(),LogWarning() ve LogMessage() iletileri hata listesinin farklı bölümlerine yerleştirecektir.
Doğrulama Yöntemleri Nasıl Uygulanır
Doğrulama, sınıf öznitelikleri ve işlem parametreleri gibi model içerisindeki ilişkileri ve büyük öğelerin parçaları dahil olmak üzere her öğeye uygulanır.
Her doğrulama yöntemi ikinci parametresindeki türe uyan her öğeye uygulanır.Bu şu demektir, örneğin eğer doğrulama yöntemini IUseCase'in ikinci parametresi ile diğerini IElement supertype'ı ile tanımlarsanız, bu yöntemlerin ikisi de modeldeki her kullanım örneğine uygulanacaktır.
Türlerin hiyerarşisi Model Öğe Türleri'ta özetlenmiştir.
Ayrıca öğelere ilişkileri takip ederek de erişebilirsiniz.Örneğin, IClass'ta doğrulama yöntemi tanımlamak için, onun kendi özellikleri boyunca döngüye girebilirsiniz:
public void ValidateTypeName(ValidationContext context, IClass c)
{
foreach (IProperty property in c.OwnedAttributes)
{
if (property.Name.Length < 3)
{
context.LogError(
string.Format(
"Property name {0} is too short",
property.Name),
"001", property);
}
}
}
Model üzerinde doğrulama yöntemi oluşturma
Eğer doğrulama yönteminin her doğrulama çalışması esnasında tam olarak bir kez çağrıldığından emin olmak istiyorsanız, IModel'i doğrulayabilirsiniz.
using Microsoft.VisualStudio.Uml.AuxiliaryConstructs; ...
[Export(typeof(System.Action<ValidationContext, object>))]
[ValidationMethod(ValidationCategories.Menu)]
public void ValidateModel(ValidationContext context, IModel model)
{ foreach (IElement element in model.OwnedElements)
{ ...
Şekil ve diyagramları doğrulama
Doğrulama yöntemleri diyagramlar ve şekiller gibi görüntüleme öğeleri üzerinde çağrılmaz, çünkü doğrulama yöntemlerinin birincil amacı modeli doğrulamaktır.Ancak diyagram bağlamını kullanarak geçerli diyagrama erişebilirsiniz.
Doğrulama sınıfında, DiagramContext'ini içeri aktarılan özellik olarak bildirin:
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation;
...
[Import]
public IDiagramContext DiagramContext { get; set; }
Doğrulama yönteminde, eğer varsa, geçerli odak diyagramına erişmek için DiagramContext'i kullanabilirsiniz:
[Export(typeof(System.Action<ValidationContext, object>))]
[ValidationMethod(ValidationCategories.Menu)]
public void ValidateModel(ValidationContext context, IModel model)
{
IDiagram focusDiagram = DiagramContext.CurrentDiagram;
if (focusDiagram != null)
{
foreach (IShape<IUseCase> useCaseShape in
focusDiagram.GetChildShapes<IUseCase>())
{ ...
Bir hatayı kaydetmek için şeklin gösterdiği model öğeyi edinmeniz gerekir çünkü şekli LogError'a geçiremezsiniz:
IUseCase useCase = useCaseShape.Element;
context.LogError(... , usecase);
Birden Çok Doğrulamayı Düzenleme
Örneğin kullanıcı tarafından bir diyagram menüsünden doğrulama çağrıldığında her doğrulama yöntemi, her model öğesine uygulanır.Bu, doğrulama çerçevesinin tek bir çağırmasında aynı yöntemin farklı öğelere birçok kez uygulanabileceği anlamına gelir.
Bu, öğeler arasındaki ilişkilerle ilgilenen bir doğrulama problemini sunar.Örneğin, kullanım örneğinden başlayan ve döngü olmadığını kanıtlamak için include ilişkilerinden geçen bir doğrulama yazabilirsiniz.Ancak yöntem birçok include bağlantısı olan modelde her kullanım örneğine uygulandığı zaman, büyük olasılıkla sürekli olarak modelin aynı alanlarını işleyecektir.
Bu durumdan kaçınmak için, doğrulama çalışması esnasında bilgilerin korunduğu bağlam önbelleği vardır.Doğrulama yöntemlerinin yürütmeleri arasında bilgi geçirmek için bağlam önbelleğini kullanabilirsiniz.Örneğin, bu doğrulama çalışmasında zaten ele alınmış olan öğelerin listesini saklayabilirsiniz.Önbellek her doğrulama çalışmasının başlangıcında oluşturulur ve farklı doğrulama çalışmaları arasında bilgi geçirmek için kullanılamaz.
context.SetCacheValue<T> (name, value) |
Bir değer saklar |
context.TryGetCacheValue<T> (name, out value) |
Bir değer alır.Başarılı olursa true döndürür. |
context.GetValue<T>(name) |
Bir değer alır. |
Context.GetValue<T>() |
Belirtilen türde bir değer alır. |
Bir uzantıyı yükleme ve kaldırma
Visual Studio'yu hem kendi bilgisayarınıza hem de diğer bilgisayarlara yükleyebilirsiniz.
Bir uzantı yüklemek için
Bilgisayarınızda, VSIX projeniz tarafından oluşturulmuş .vsix dosyasını bulun.
Çözüm Gezgini'nde, VSIX projesinin kısayol menüsünde Klasörü Windows Gezgini'nde Aç'ı seçin.
bin\*\YourProject.vsix dosyasını bulun
Uzantıyı yüklemek istediğiniz hedef bilgisayara .vsix dosyasını kopyalayın.Bu sizin kendi bilgisayarınız veya başka bir tane olabilir.
- Hedef bilgisayarda source.extension.vsixmanifest'te belirttiğiniz Visual Studio'nun sürümlerinden biri olmalıdır.
Hedef bilgisayarda .vsix dosyasını açın.
Visual Studio Uzantı Yükleyicisi açılır ve uzantıyı yükler.
Visual Studio öğesini başlatın veya yeniden başlatın.
Bir uzantıyı kaldırmak için
Araçlar menüsünde, Uzantı Yöneticisi'ni seçin.
Yüklü Uzantılar'ı genişletin.
Uzantıyı seçin ve sonra Kaldır'ı seçin.
Nadiren, hatalı bir uzantı yüklemede başarısız olur ve hata penceresinde bir rapor oluşturur, ancak Uzantı Yöneticisi'nde görünmez.Bu durumda uzantıyı dosyayı %LocalAppData% öğesinin DriveName:\Users\UserName\AppData\Local olduğu şu konumdan silerek kaldırabilirsiniz:
%LocalAppData%\Microsoft\VisualStudio\12.0\Extensions
Örnek
Bu örnek, öğeler arasındaki Bağımlılık ilişkisindeki döngüleri bulur.
Hem kaydetme hem de doğrulama menü komutunu doğrulayacaktır.
/// <summary>
/// Verify that there are no loops in the dependency relationsips.
/// In our project, no element should be a dependent of itself.
/// </summary>
/// <param name="context">Validation context for logs.</param>
/// <param name="element">Element to start validation from.</param>
[Export(typeof(System.Action<ValidationContext, object>))]
[ValidationMethod(ValidationCategories.Menu
| ValidationCategories.Save | ValidationCategories.Open)]
public void NoDependencyLoops(ValidationContext context, INamedElement element)
{
// The validation framework will call this method
// for every element in the model. But when we follow
// the dependencies from one element, we will validate others.
// So we keep a list of the elements that we don't need to validate again.
// The list is kept in the context cache so that it is passed
// from one execution of this method to another.
List<INamedElement> alreadySeen = null;
if (!context.TryGetCacheValue("No dependency loops", out alreadySeen))
{
alreadySeen = new List<INamedElement>();
context.SetCacheValue("No dependency loops", alreadySeen);
}
NoDependencyLoops(context, element,
new INamedElement[0], alreadySeen);
}
/// <summary>
/// Log an error if there is any loop in the dependency relationship.
/// </summary>
/// <param name="context">Validation context for logs.</param>
/// <param name="element">The element to be validated.</param>
/// <param name="dependants">Elements we've followed in this recursion.</param>
/// <param name="alreadySeen">Elements that have already been validated.</param>
/// <returns>true if no error was detected</returns>
private bool NoDependencyLoops(ValidationContext context,
INamedElement element, INamedElement[] dependants,
List<INamedElement> alreadySeen)
{
if (dependants.Contains(element))
{
context.LogError(string.Format("{0} should not depend on itself", element.Name),
"Fabrikam.UML.NoGenLoops", // unique code for this error
dependants.SkipWhile(e => e != element).ToArray());
// highlight elements that are in the loop
return false;
}
INamedElement[] dependantsPlusElement =
new INamedElement[dependants.Length + 1];
dependants.CopyTo(dependantsPlusElement, 0);
dependantsPlusElement[dependantsPlusElement.Length - 1] = element;
if (alreadySeen.Contains(element))
{
// We have already validated this when we started
// from another element during this validation run.
return true;
}
alreadySeen.Add(element);
foreach (INamedElement supplier in element.GetDependencySuppliers())
{
if (!NoDependencyLoops(context, supplier,
dependantsPlusElement, alreadySeen))
return false;
}
return true;
}