Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Kod oluşturma, kesin olarak yazılan ve ancak kaynak model değiştiğinde kolayca değiştirilebilen program kodu oluşturmanıza olanak tanır. Bunu, daha esnek bir yapılandırma dosyası kabul eden, ancak okunması ve değiştirilmesi çok kolay olmayan ve bu kadar iyi performansa sahip kodlarla sonuçlanan tamamen genel bir program yazmanın alternatif tekniğiyle karşıtlık edin. Bu kılavuzda bu avantaj gösterilmektedir.
XML okumak için yazılan kod
System.Xml ad alanı, BIR XML belgesini yüklemek ve ardından bellekte serbestçe gezinmek için kapsamlı araçlar sağlar. Ne yazık ki, tüm düğümler aynı türe sahiptir: XmlNode. Bu nedenle, yanlış alt düğüm türünü veya yanlış öznitelikleri bekleme gibi programlama hataları yapmak çok kolaydır.
Bu örnek projede bir şablon örnek XML dosyasını okur ve her düğüm türüne karşılık gelen sınıflar oluşturur. El ile yazılmış kodda, XML dosyasında gezinmek için bu sınıfları kullanabilirsiniz. Uygulamanızı aynı düğüm türlerini kullanan diğer tüm dosyalarda da çalıştırabilirsiniz. Örnek XML dosyasının amacı, uygulamanızın ilgilenmesini istediğiniz tüm düğüm türlerinin örneklerini sağlamaktır.
Not
Visual Studio'ya dahil edilen xsd.exe uygulaması, XML dosyalarından kesin olarak türlenmiş sınıflar oluşturabilir. Burada gösterilen şablon örnek olarak verilmiştir.
Örnek dosya şu şekildedir:
<?xml version="1.0" encoding="utf-8" ?>
<catalog>
<artist id ="Mike%20Nash" name="Mike Nash Quartet">
<song id ="MikeNashJazzBeforeTeatime">Jazz Before Teatime</song>
<song id ="MikeNashJazzAfterBreakfast">Jazz After Breakfast</song>
</artist>
<artist id ="Euan%20Garden" name="Euan Garden">
<song id ="GardenScottishCountry">Scottish Country Garden</song>
</artist>
</catalog>
Bu kılavuzda oluşturulan projede, aşağıdaki gibi bir kod yazabilirsiniz ve Siz yazarken IntelliSense sizden doğru öznitelik ve alt adları ister:
Catalog catalog = new Catalog(xmlDocument);
foreach (Artist artist in catalog.Artist)
{
Console.WriteLine(artist.name);
foreach (Song song in artist.Song)
{
Console.WriteLine(" " + song.Text);
}
}
Bunu, şablon olmadan yazabileceğiniz yazılmamış kodla karşıtlayın:
XmlNode catalog = xmlDocument.SelectSingleNode("catalog");
foreach (XmlNode artist in catalog.SelectNodes("artist"))
{
Console.WriteLine(artist.Attributes["name"].Value);
foreach (XmlNode song in artist.SelectNodes("song"))
{
Console.WriteLine(" " + song.InnerText);
}
}
Kesin olarak yazılan sürümde, XML şemasında yapılan bir değişiklik sınıflarda değişikliklere neden olur. Derleyici, uygulama kodunun değiştirilmesi gereken bölümlerini vurgular. Genel XML kodu kullanan yazılmamış sürümde böyle bir destek yoktur.
Bu projede, yazılan sürümü mümkün hale getiren sınıfları oluşturmak için tek bir şablon dosyası kullanılır.
Projeyi ayarlama
C# projesi oluşturma veya açma
Bu tekniği herhangi bir kod projesine uygulayabilirsiniz. Bu izlenecek yol bir C# projesi kullanır ve test amacıyla bir konsol uygulaması kullanırız.
Dosya menüsünde Yeni'ye ve ardından Proje'ye tıklayın.
Visual C# düğümüne tıklayın ve şablonlar bölmesinde Konsol Uygulaması'na tıklayın.
Projeye prototip XML dosyası ekleme
Bu dosyanın amacı, uygulamanızın okuyabilmesini istediğiniz XML düğümü türlerinin örneklerini sağlamaktır. Uygulamanızı test etme amacıyla kullanılacak bir dosya olabilir. Şablon, bu dosyadaki her düğüm türü için bir C# sınıfı oluşturur.
Dosyanın, şablonun okuyabilmesi için projenin bir parçası olması gerekir, ancak derlenen uygulamada yerleşik olmaz.
Çözüm Gezgini, projeye sağ tıklayın, Ekle'ye ve ardından Yeni Öğe'ye tıklayın.
Yeni Öğe Ekle iletişim kutusunda, Şablonlar bölmesinden XML Dosyası'nı seçin.
Örnek içeriğinizi dosyaya ekleyin.
Bu izlenecek yol için dosyasını
exampleXml.xmlolarak adlandırın. Dosyanın içeriğini önceki bölümde gösterilen XML olarak ayarlayın.
Test kodu dosyası ekleme
Projenize bir C# dosyası ekleyin ve yazabilmek istediğiniz kodun bir örneğini yazın. Örneğin:
using System;
namespace MyProject
{
class CodeGeneratorTest
{
public void TestMethod()
{
Catalog catalog = new Catalog(@"..\..\exampleXml.xml");
foreach (Artist artist in catalog.Artist)
{
Console.WriteLine(artist.name);
foreach (Song song in artist.Song)
{
Console.WriteLine(" " + song.Text);
} } } } }
Bu aşamada, bu kod derlenemiyor. Şablonu yazarken, başarılı olmasını sağlayan sınıflar oluşturacaksınız.
Daha kapsamlı bir test, bu test işlevinin çıkışını örnek XML dosyasının bilinen içeriğiyle karşılaştırabilir. Ancak bu kılavuzda, test yöntemi derlendiğinde memnun olacağız.
Metin şablonu dosyası ekleme
Bir metin şablonu dosyası ekleyin ve çıkış uzantısını .cs olarak ayarlayın.
Çözüm Gezgini'da projeye sağ tıklayın, Ekle'ye ve ardından Yeni Öğe'ye tıklayın.
Yeni Öğe Ekle iletişim kutusunda, Şablonlar bölmesinden Metin Şablonu'nu seçin.
Not
Önceden İşlenmiş Metin Şablonu değil, Metin Şablonu eklediğinizden emin olun.
dosyasındaki şablon yönergesinde özniteliğini
hostspecificolaraktruedeğiştirin.Bu değişiklik, şablon kodunun Visual Studio hizmetlerine erişmesini sağlar.
Çıkış yönergesinde uzantı özniteliğini ".cs" olarak değiştirerek şablonun bir C# dosyası oluşturmasını sağlayın. Visual Basic projesinde bunu ".vb" olarak değiştirirsiniz.
Dosyayı kaydedin. Bu aşamada, metin şablonu dosyası şu satırları içermelidir:
<#@ template debug="false" hostspecific="true" language="C#" #> <#@ output extension=".cs" #>
.cs dosyasının şablon dosyasının yan kuruluşu olarak Çözüm Gezgini göründüğüne dikkat edin. Şablon dosyasının adının yanındaki [+] öğesine tıklayarak bunu görebilirsiniz. Bu dosya, odağı şablon dosyasından her kaydettiğinizde veya kaldırdığınızda şablon dosyasından oluşturulur. Oluşturulan dosya projenizin bir parçası olarak derlenir.
Şablon dosyasını geliştirirken kolaylık sağlamak için, şablon dosyasının pencerelerini ve oluşturulan dosyayı yan yana görebilecek şekilde düzenleyin. Bu, şablonunuzun çıktısını hemen görmenizi sağlar. Ayrıca, şablonunuz geçersiz C# kodu oluşturduğunda hata iletisi penceresinde hataların görüneceğini de fark edeceksiniz.
Doğrudan oluşturulan dosyada yaptığınız tüm düzenlemeler, şablon dosyasını her kaydettiğinizde kaybolur. Bu nedenle, oluşturulan dosyayı düzenlemekten kaçınmanız veya yalnızca kısa denemeler için düzenlemeniz gerekir. IntelliSense'in çalışmakta olduğu oluşturulan dosyada kısa bir kod parçasını denemek ve ardından şablon dosyasına kopyalamak bazen yararlıdır.
Metin Şablonunu Geliştirme
Çevik geliştirmeyle ilgili en iyi öneriyi izleyerek, test kodu derlenip doğru şekilde çalıştırılana kadar şablonu küçük adımlarla geliştireceğiz ve her bir artışta bazı hataları temizleyeceğiz.
Oluşturulacak kodun prototipini oluşturma
Test kodu, dosyadaki her düğüm için bir sınıf gerektirir. Bu nedenle, bu satırları şablona ekler ve sonra kaydederseniz derleme hatalarından bazıları kaybolur:
class Catalog {}
class Artist {}
class Song {}
Bu, nelerin gerekli olduğunu görmenize yardımcı olur, ancak bildirimlerin örnek XML dosyasındaki düğüm türlerinden oluşturulması gerekir. Bu deneysel satırları şablondan silin.
Model XML dosyasından uygulama kodu oluşturma
XML dosyasını okumak ve sınıf bildirimleri oluşturmak için şablon içeriğini aşağıdaki şablon koduyla değiştirin:
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Xml"#>
<#@ import namespace="System.Xml" #>
<#
XmlDocument doc = new XmlDocument();
// Replace this file path with yours:
doc.Load(@"C:\MySolution\MyProject\exampleXml.xml");
foreach (XmlNode node in doc.SelectNodes("//*"))
{
#>
public partial class <#= node.Name #> {}
<#
}
#>
Dosya yolunu projeniz için doğru yolla değiştirin.
Kod bloğu sınırlayıcılarını <#...#>dikkate alır. Bu sınırlayıcılar, program kodunun metni oluşturan bir parçasını köşeli ayraç içine alır. İfade bloğu sınırlayıcıları <#=...#> , bir dize olarak değerlendirilebilecek bir ifadeyi köşeli ayraç içine alır.
Uygulamanız için kaynak kodu oluşturan bir şablon yazarken, iki ayrı program metniyle ilgileniyorsunuz. Kod bloğu sınırlayıcıları içindeki program, şablonu kaydettiğinizde veya odağı başka bir pencereye taşıdığınızda çalışır. Oluşturduğu ve sınırlayıcıların dışında görünen metin, oluşturulan dosyaya kopyalanır ve uygulama kodunuzun bir parçası olur.
yönergesi <#@assembly#> bir başvuru gibi davranarak derlemeyi şablon kodu için kullanılabilir hale getirir. Şablon tarafından görülen derlemelerin listesi, uygulama projesindeki Başvurular listesinden ayrıdır.
yönergesi <#@import#> , içeri aktarılan ad alanında sınıfların kısa adlarını kullanmanıza olanak sağlayan bir using deyim gibi davranır.
Ne yazık ki, bu şablon kod oluştursa da, örnek XML dosyasındaki her düğüm için bir sınıf bildirimi oluşturur, böylece düğümün <song> birkaç örneği varsa, sınıf şarkısının çeşitli bildirimleri görünür.
Model dosyasını okuyun ve kodu oluşturun
Birçok metin şablonu, şablonun ilk bölümünün kaynak dosyayı okuduğu ve ikinci bölümün şablonu oluşturduğu bir desen izler. içerdiği düğüm türlerini özetlemek için örnek dosyanın tamamını okumamız ve ardından sınıf bildirimlerini oluşturmamız gerekir. Kullanabilmemiz için başka bir <#@import#> gereklidir Dictionary<>:
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Xml"#>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Collections.Generic" #>
<#
// Read the model file
XmlDocument doc = new XmlDocument();
doc.Load(@"C:\MySolution\MyProject\exampleXml.xml");
Dictionary <string, string> nodeTypes =
new Dictionary<string, string>();
foreach (XmlNode node in doc.SelectNodes("//*"))
{
nodeTypes[node.Name] = "";
}
// Generate the code
foreach (string nodeName in nodeTypes.Keys)
{
#>
public partial class <#= nodeName #> {}
<#
}
#>
Yardımcı yöntem ekleme
Sınıf özellik denetim bloğu, yardımcı yöntemleri tanımlayabildiğiniz bir bloktır. bloğu ile sınırlandırılır <#+...#> ve dosyadaki son blok olarak görünmelidir.
Sınıf adlarının büyük harfle başlamasını tercih ediyorsanız, şablonun son bölümünü aşağıdaki şablon koduyla değiştirebilirsiniz:
// Generate the code
foreach (string nodeName in nodeTypes.Keys)
{
#>
public partial class <#= UpperInitial(nodeName) #> {}
<#
}
#>
<#+
private string UpperInitial(string name)
{ return name[0].ToString().ToUpperInvariant() + name.Substring(1); }
#>
Bu aşamada, oluşturulan .cs dosyası aşağıdaki bildirimleri içerir:
public partial class Catalog {}
public partial class Artist {}
public partial class Song {}
Alt düğümlerin özellikleri, öznitelikler ve iç metin gibi diğer ayrıntılar aynı yaklaşım kullanılarak eklenebilir.
Visual Studio API'sine erişme
yönergesinin hostspecific özniteliğini <#@template#> ayarlamak, şablonun Visual Studio API'sine erişim elde etmesini sağlar. Şablon, şablon kodunda mutlak bir dosya yolu kullanmaktan kaçınmak için proje dosyalarının konumunu almak için bunu kullanabilir.
<#@ template debug="false" hostspecific="true" language="C#" #>
...
<#@ assembly name="EnvDTE" #>
...
EnvDTE.DTE dte = (EnvDTE.DTE) ((IServiceProvider) this.Host)
.GetService(typeof(EnvDTE.DTE));
// Open the prototype document.
XmlDocument doc = new XmlDocument();
doc.Load(System.IO.Path.Combine(dte.ActiveDocument.Path, "exampleXml.xml"));
Metin Şablonunu Tamamlama
Aşağıdaki şablon içeriği, test kodunun derlenip çalıştırılmasını sağlayan kod oluşturur.
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="EnvDTE" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Collections.Generic" #>
using System;using System.Collections.Generic;using System.Linq;using System.Xml;namespace MyProject{
<#
// Map node name --> child name --> child node type
Dictionary<string, Dictionary<string, XmlNodeType>> nodeTypes = new Dictionary<string, Dictionary<string, XmlNodeType>>();
// The Visual Studio host, to get the local file path.
EnvDTE.DTE dte = (EnvDTE.DTE) ((IServiceProvider) this.Host)
.GetService(typeof(EnvDTE.DTE));
// Open the prototype document.
XmlDocument doc = new XmlDocument();
doc.Load(System.IO.Path.Combine(dte.ActiveDocument.Path, "exampleXml.xml"));
// Inspect all the nodes in the document.
// The example might contain many nodes of the same type,
// so make a dictionary of node types and their children.
foreach (XmlNode node in doc.SelectNodes("//*"))
{
Dictionary<string, XmlNodeType> subs = null;
if (!nodeTypes.TryGetValue(node.Name, out subs))
{
subs = new Dictionary<string, XmlNodeType>();
nodeTypes.Add(node.Name, subs);
}
foreach (XmlNode child in node.ChildNodes)
{
subs[child.Name] = child.NodeType;
}
foreach (XmlNode child in node.Attributes)
{
subs[child.Name] = child.NodeType;
}
}
// Generate a class for each node type.
foreach (string className in nodeTypes.Keys)
{
// Capitalize the first character of the name.
#>
partial class <#= UpperInitial(className) #>
{ private XmlNode thisNode; public <#= UpperInitial(className) #>(XmlNode node) { thisNode = node; }
<#
// Generate a property for each child.
foreach (string childName in nodeTypes[className].Keys)
{
// Allow for different types of child.
switch (nodeTypes[className][childName])
{
// Child nodes:
case XmlNodeType.Element:
#>
public IEnumerable<<#=UpperInitial(childName)#>><#=UpperInitial(childName) #> { get { foreach (XmlNode node in thisNode.SelectNodes("<#=childName#>")) yield return new <#=UpperInitial(childName)#>(node); } }
<#
break;
// Child attributes:
case XmlNodeType.Attribute:
#>
public string <#=childName #> { get { return thisNode.Attributes["<#=childName#>"].Value; } }
<#
break;
// Plain text:
case XmlNodeType.Text:
#>
public string Text { get { return thisNode.InnerText; } }
<#
break;
} // switch
} // foreach class child
// End of the generated class:
#>
}
<#
} // foreach class
// Add a constructor for the root class
// that accepts an XML filename.
string rootClassName = doc.SelectSingleNode("*").Name;
#>
partial class <#= UpperInitial(rootClassName) #> { public <#= UpperInitial(rootClassName) #>(string fileName){ XmlDocument doc = new XmlDocument(); doc.Load(fileName); thisNode = doc.SelectSingleNode("<#=rootClassName#>");} }}
<#+
private string UpperInitial(string name)
{
return name[0].ToString().ToUpperInvariant() + name.Substring(1);
}
#>
Test programını çalıştırma
Konsol uygulamasının ana bölümünde aşağıdaki satırlar test yöntemini yürütür. Programı hata ayıklama modunda çalıştırmak için F5 tuşuna basın:
using System;
namespace MyProject
{
class Program
{
static void Main(string[] args)
{
new CodeGeneratorTest().TestMethod();
// Allow user to see the output:
Console.ReadLine();
}
}
}
Uygulamayı yazma ve güncelleştirme
Uygulama artık, genel XML kodu yerine oluşturulan sınıflar kullanılarak kesin olarak yazılmış bir stilde yazılabilir.
XML şeması değiştiğinde, yeni sınıflar kolayca oluşturulabilir. Derleyici, geliştiriciye uygulama kodunun güncelleştirileceği yeri bildirir.
Örnek XML dosyası değiştirildiğinde sınıfları yeniden oluşturmak için Çözüm Gezgini araç çubuğunda Tüm Şablonları Dönüştür'e tıklayın.
Sonuç
Bu izlenecek yol, kod oluşturmanın çeşitli tekniklerini ve avantajlarını gösterir:
Kod oluşturma , uygulamanızın kaynak kodunun bir kısmının bir modelden oluşturulmasıdır. Model, uygulama etki alanına uygun bir biçimde bilgi içerir ve uygulamanın kullanım ömrü boyunca değişebilir.
Güçlü yazma, kod oluşturmanın avantajlarından biridir. Model, kullanıcıya daha uygun bir biçimdeki bilgileri temsil ederken, oluşturulan kod uygulamanın diğer bölümlerinin bir tür kümesi kullanarak bilgilerle ilgilenmesine olanak tanır.
IntelliSense ve derleyici, hem yeni kod yazdığınızda hem de şema güncelleştirildiğinde modelin şemasına uygun kod oluşturmanıza yardımcı olur.
Bir projeye tek bir karmaşık olmayan şablon dosyasının eklenmesi bu avantajları sağlayabilir.
Metin şablonu hızla ve artımlı olarak geliştirilebilir ve test edilebilir.
Bu kılavuzda program kodu, uygulamanın işleyecekleri XML dosyalarının temsili bir örneği olan modelin bir örneğinden oluşturulur. Daha resmi bir yaklaşımda XML şeması, .xsd dosyası veya etki alanına özgü bir dil tanımı biçiminde şablona giriş olacaktır. Bu yaklaşım, şablonun bir ilişkinin çokluğu gibi özellikleri belirlemesini kolaylaştırır.
Metin Şablonu sorunlarını giderme
Hata Listesi'nde şablon dönüştürme veya derleme hataları gördüyseniz veya çıkış dosyası doğru oluşturulmadıysa, Metin Çevirisi Yardımcı Programı ile Dosya Oluşturma bölümünde açıklanan tekniklerle metin şablonu sorunlarını giderebilirsiniz.