掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢(xún)/運(yùn)營(yíng)咨詢(xún)/技術(shù)建議/互聯(lián)網(wǎng)交流
Visual Studio DSL也成為Visual Studio特定領(lǐng)域開(kāi)發(fā),之前我們報(bào)道過(guò)《淺析Visual Studio中的特定領(lǐng)域開(kāi)發(fā)》,而本文也是Visual Studio特定領(lǐng)域開(kāi)發(fā)系列文章中關(guān)于生成域類(lèi)和域關(guān)系的部分。

#T#
上一節(jié)我們大概介紹了一些Vs.net Dsl的域模型的一些基本的概念,這一節(jié)我們?cè)倩氐轿覀兩傻腖anuageSm項(xiàng)目,看一下生成的域類(lèi)以及域關(guān)系,介紹一下Dsl運(yùn)行時(shí)的Store,然后再來(lái)介紹一下需要注意的一些關(guān)鍵點(diǎn)。為我們下一節(jié)具體設(shè)計(jì)我們自己的Dsl做最后的準(zhǔn)備.
1. 首先找到Dsl項(xiàng)目中模板DomainClasses.tt生成的DomainClasses.cs,我們來(lái)查看一下它由兩個(gè)類(lèi)組成:
其實(shí)也就對(duì)應(yīng)著我們域模型中的根域類(lèi)ExampleModel和域類(lèi)ExampleElement.我們仔細(xì)再來(lái)看一下ExampleElement類(lèi)的具體結(jié)構(gòu).可以發(fā)現(xiàn):
1).字段是Guid類(lèi)型的,這樣更方便關(guān)系類(lèi)中直接引用屬性,后續(xù)我們也會(huì)發(fā)現(xiàn)在驗(yàn)證,規(guī)則中也會(huì)經(jīng)常使用屬性的Guid字段變量來(lái)代表屬性.
2).我們看到上一節(jié)我們看到的關(guān)系生成的屬性,ExampleElement與ExampleModel的嵌入關(guān)系,生成了ExampleModel類(lèi)型的ExampleModel屬性. ExampleElement與自身的引用關(guān)系,由于重?cái)?shù)是*,生成了強(qiáng)集合類(lèi)型LinkedElementCollection
3).屬性中的Name代表域類(lèi)的域?qū)傩訬ame。
2. 我們?cè)賮?lái)看一下域關(guān)系,找到DomainRelationships.tt生成的類(lèi)文件DomainRelationships.cs,查看類(lèi)圖,顯示類(lèi)圖中的屬性為關(guān)系或者是組合關(guān)系:
1)可以看到域關(guān)系對(duì)應(yīng)的類(lèi)通過(guò)Guid對(duì)應(yīng)的字段關(guān)聯(lián)域類(lèi).
2)通過(guò)上面的類(lèi)圖,可以看到域關(guān)系類(lèi)對(duì)應(yīng)的屬性與域類(lèi)的關(guān)系,它分別存儲(chǔ)了關(guān)系對(duì)應(yīng)的源Source和目標(biāo)Target的屬性。
3)我們可以找到一些靜態(tài)方法,比如在ExampleModelHasElements類(lèi)中:
GetElements(ExampleModel) --- 獲取關(guān)系中一個(gè)ExampleModel對(duì)應(yīng)的所有的ExampleElement
GetExampleModel(ExampleElement) --獲取關(guān)系中一個(gè)ExampleElement對(duì)應(yīng)的ExampleModel
另外還可以通過(guò)GetLink,GetLinks, GetLinksToElements,獲取指定元素之間的關(guān)系。
3.很有必要在這里也對(duì)Dsl的運(yùn)行的機(jī)制有一些了解 ,那就必須在這里介紹一下Store.
1)在Dsl運(yùn)行期間,模型元素都被存儲(chǔ)在內(nèi)存中的Store中,Sotre也提供了一系列的操作:模型元素和關(guān)系的創(chuàng)建,操作,刪除,Redo/Undo,規(guī)則,事件等,相當(dāng)重要,在Dsl開(kāi)發(fā)中經(jīng)常會(huì)涉及到Store的操作。
2)當(dāng)一個(gè)模型文件被打開(kāi)時(shí),會(huì)自動(dòng)重建一個(gè)Store,并且加載模型文件中的所有的模型和關(guān)系的實(shí)例,這個(gè)過(guò)程我們會(huì)在后面介紹。
3) 每一個(gè)域類(lèi)都繼承ModelElement,每個(gè)域關(guān)系都繼承自ElementLink(ElementLink其實(shí)也繼承于ModelElement). 在Store中加載的每個(gè)模型其實(shí)都是ModelEment的一個(gè)實(shí)例,每個(gè)域關(guān)系都是ElementLink的一個(gè)實(shí)例??梢酝ㄟ^(guò)Store甚至可以操作它們的屬性,監(jiān)聽(tīng)創(chuàng)建,刪除等事件.
4.有一些細(xì)節(jié)性的應(yīng)該注意的問(wèn)題在這里零散的總結(jié)一下:
1).區(qū)分兩個(gè)域類(lèi)是嵌入關(guān)系還是引用關(guān)系,可以考慮這域類(lèi)在模型瀏覽器里的展現(xiàn),如果嵌入在模型瀏覽器中(Model Explorer)那就可以采用嵌入關(guān)系,否則就是引用關(guān)系.
2).關(guān)系的重?cái)?shù)雖然可以任意選擇,但是在有些情況下會(huì)有些限制,比如在嵌入式關(guān)系中:
嵌入關(guān)系目標(biāo)角色的重?cái)?shù)可為One 或者是ZeroOne,因?yàn)橐粋€(gè)ModelElement只能被嵌入一次.
如果一個(gè)ModelElement是多個(gè)嵌入關(guān)系中的目標(biāo)角色,那么目標(biāo)角色的重?cái)?shù)必須都為ZeroOne,因?yàn)樗荒茉谕粫r(shí)間在一個(gè)關(guān)系中扮演目標(biāo)角色。
在一個(gè)完整的域模型中,每個(gè)域類(lèi)(根域類(lèi)除外)必須是一個(gè)嵌入關(guān)系的目標(biāo),不然就不能夠構(gòu)成一個(gè)完整的模型樹(shù),也就不能夠處理序列化
當(dāng)然,可能大家會(huì)對(duì)這些規(guī)則有些不知所措,沒(méi)關(guān)系,你可以不理這些規(guī)則,按照你的方式去設(shè)計(jì),在保存或者是驗(yàn)證(右鍵Validate All)時(shí),會(huì)在下面的錯(cuò)誤窗口提示你的。
3)每個(gè)域類(lèi)都應(yīng)該有Name Domain Property.可以通過(guò)從工具欄拖Named Domain Class創(chuàng)建域類(lèi),自動(dòng)帶出此域?qū)傩?,也可以手?dòng)添加域?qū)傩?,然后指定域?qū)傩缘腎s Element Name 為T(mén)rue,此屬性的值會(huì)在序列化處理時(shí)使用.
鏈接:http://www.cnblogs.com/lonely7345/archive/2010/01/29/1659157.html

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢(xún)/運(yùn)營(yíng)咨詢(xún)/技術(shù)建議/互聯(lián)網(wǎng)交流