Megosztás a következőn keresztül:


Fájltárolás és XML-szerializálás testreszabása

Amikor a felhasználó egy tartományspecifikus nyelv (DSL) egy példányát vagy modellmenti a Visual Studióban, létrejön vagy frissül egy XML-fájl. A fájl újra betölthető a modell újbóli létrehozásához az Áruházban.

A szerializálási sémát a DSL Explorer Xml Szerializálási viselkedés beállításainak módosításával szabhatja testre. Minden tartományosztályhoz, tulajdonsághoz és kapcsolathoz tartozik egy csomópont Xml szerializálási viselkedési alatt. A kapcsolatok a forrásosztályaik alatt találhatók. Vannak az alakzat-, összekötő- és diagramosztályoknak megfelelő csomópontok is.

A speciálisabb testreszabáshoz programkódot is írhat.

Jegyzet

Ha egy adott formátumban szeretné menteni a modellt, de nem kell újra betöltenie az űrlapról, fontolja meg a szövegsablonok használatát a modell kimenetének létrehozásához egyéni szerializálási séma helyett. További információkért lásd: Kód generálása Domain-Specificnyelvről.

Modell- és diagramfájlok

Minden modell két fájlba van mentve:

  • A modellfájl neve például Model1.mydsl. Tárolja a modell elemeit és kapcsolatait, valamint azok tulajdonságait. A fájlkiterjesztést( például .mydsl) a DSL-definíció Szerkesztő csomópontjának FileExtension tulajdonsága határozza meg.

  • A diagramfájl neve például Model1.mydsl.diagram. Tárolja az alakzatokat, összekötőket és azok pozícióit, színeit, vonalvastagságait és a diagram megjelenésének egyéb részleteit. Ha a felhasználó töröl egy .diagram fájlt, a modell alapvető információi nem vesznek el. Csak a diagram elrendezése veszett el. A modellfájl megnyitásakor létrejön egy alapértelmezett alakzat- és összekötőkészlet.

DSL fájlkiterjesztésének módosítása

  1. Nyissa meg a DSL-definíciót. A DSL Explorerben kattintson a Szerkesztő csomópontra.

  2. A Tulajdonságok ablakban szerkessze a FileExtension tulajdonságot. Ne tartalmazza a fájlnévkiterjesztés kezdeti ..

  3. A Megoldáskezelőben módosítsa a két elemsablon fájljainak nevét a DslPackage\ProjectItemTemplates. Ezek a fájlok a következő formátumot követik:

    myDsl.diagram

    myDsl.myDsl

Az alapértelmezett szerializálási séma

A témakörhöz a következő DSL-definíciót használtuk példaként.

DSL-definíciós diagram – családfamodell

Ez a DSL egy olyan modell létrehozására szolgál, amely a következő megjelenéssel rendelkezik a képernyőn.

Családfa diagram, eszközkészlet és Explorer

Ezt a modellt mentette, majd újra megnyitotta az XML-szövegszerkesztőben:

<?xml version="1.0" encoding="utf-8"?>
<familyTreeModel xmlns:dm0="http://schemas.microsoft.com/VisualStudio/2008/DslTools/Core" dslVersion="1.0.0.0" Id="f817b728-e920-458e-bb99-98edc469d78f" xmlns="http://schemas.microsoft.com/dsltools/FamilyTree">
  <people>
    <person name="Henry VIII" birthYear="1491" deathYear="1547" age="519">
      <children>
        <personMoniker name="/f817b728-e920-458e-bb99-98edc469d78f/Elizabeth I" />
        <personMoniker name="/f817b728-e920-458e-bb99-98edc469d78f/Mary" />
      </children>
    </person>
    <person name="Elizabeth I" birthYear="1533" deathYear="1603" age="477" />
    <person name="Mary" birthYear="1515" deathYear="1558" age="495" />
  </people>
</familyTreeModel>

Figyelje meg a szerializált modell alábbi pontjait:

  • Minden XML-csomópont neve megegyezik a tartományosztály nevével, azzal a kivétellel, hogy a kezdeti betű kisbetűs. Például familyTreeModel és person.

  • A tartománytulajdonságok, például a Név és a Születési év attribútumként vannak szerializálva az XML-csomópontokban. A tulajdonságnév kezdeti karaktere ismét kisbetűssé alakul.

  • Minden kapcsolat szerializálva van a kapcsolat forrásvégén belül beágyazott XML-csomópontként. A csomópont neve megegyezik a forrásszerepkör-tulajdonság nevével, de kisbetűs kezdeti karakterrel.

    A DSL-definícióban például egy Személyek nevű szerepkör a FamilyTree osztályban található. Az XML-ben a Személyek szerepkör egy people nevű csomóponttal jelenik meg, amely a familyTreeModel csomópontba van ágyazva.

  • Az egyes beágyazási kapcsolatok célvége szerializálva van a kapcsolat alá ágyazott csomópontként. A people csomópont például több person csomópontot tartalmaz.

  • Az egyes referenciakapcsolatok célvége mint monikervan szerializálva, amely a célelemre mutató hivatkozást kódol.

    Például egy person csomópont alatt lehet egy children kapcsolat. Ez a csomópont olyan monikereket tartalmaz, mint például:

    <personMoniker name="/f817b728-e920-458e-bb99-98edc469d78f/Elizabeth I" />
    

A Monikers ismertetése

A monikerek a modell és a diagramfájlok különböző részei közötti kereszthivatkozások ábrázolására szolgálnak. A .diagram fájlban is használják őket a modellfájl csomópontjaira való hivatkozáshoz. A monikernek két formája van:

  • Azonosító-monikerek idézik a célelem GUID azonosítóját. Például:

    <personShapeMoniker Id="f79734c0-3da1-4d72-9514-848fa9e75157" />
    
  • minősített kulcs monikerei a célelemet egy kijelölt tartománytulajdonság, a monikerkulcs értéke alapján azonosítják. A célelem monikerje a szülőelem monikerével van előtagban a beágyazási kapcsolatok fájában.

    A következő példák egy DSL-ből származnak, amelyben van egy Album nevű tartományosztály, amely beágyazási kapcsolatban áll egy Song nevű tartományosztálysal:

    <albumMoniker title="/My Favorites/Jazz after Teatime" />
    <songMoniker title="/My Favorites/Jazz after Teatime/Hot tea" />
    

    A minősített kulcs-monikerek akkor használatosak, ha a célzott osztály rendelkezik egy olyan tartománytulajdonsággal, amelynek A Moniker-kulcs beállítás true-re van állítva XML-szerializálási viselkedés. A példában ez a beállítás a "Cím" nevű tartománytulajdonságokhoz van beállítva az "Album" és a "Song" tartományosztályban.

A minősített kulcs monikerei könnyebben olvashatók, mint az azonosító monikerek. Ha a modellfájlok XML-jének emberi olvasásra van szüksége, fontolja meg a minősített kulcs-monikerek használatát. Előfordulhat azonban, hogy a felhasználó több elemet is beállít, hogy ugyanazzal a moniker kulccsal rendelkezzen. Az ismétlődő kulcsok miatt a fájl nem töltődik be megfelelően. Ezért ha olyan tartományosztályt határoz meg, amely minősített kulcs-monikerekkel hivatkozik, érdemes megfontolni, hogyan akadályozhatja meg a felhasználót abban, hogy duplikált monikerekkel rendelkező fájlt mentsen.

Tartományosztály beállítása azonosító-monikerek általi hivatkozásra

  1. Győződjön meg arról, hogy Is Moniker Keyfalse az osztály és annak alaposztályai minden tartománytulajdonságához.

    1. A DSL Explorerben bontsa ki a Xml szerializációs viselkedés\Osztályadatok\<tartományosztályt>\Elemadatok.

    2. Ellenőrizze, hogy a Moniker-kulcs minden tartománytulajdonsághoz false-e.

    3. Ha a tartományosztály rendelkezik alaposztálysal, ismételje meg az adott osztály eljárását.

  2. Állítsa be szerializálási azonosító = true a tartományosztályhoz.

    Ez a tulajdonság Xml szerializálási viselkedésialatt található.

Domain osztály beállítása minősített kulcsmonikerek általi hivatkozáshoz

  • Állítsa be A Moniker-kulcs beállítása egy meglévő tartományosztály tartománytulajdonságához. A tulajdonság típusának stringkell lennie.

    1. A DSL Explorerben bontsa ki Xml szerializálási viselkedés\Osztályadatok\<a tartományosztály>\Elemadatok, majd válassza ki a tartománytulajdonságot.

    2. A Tulajdonságok ablakban állítsa be a Moniker-kulcsot értékre true.

  • -vagy-

    Hozzon létre egy új tartományosztályt a Named Domain Class eszközzel.

    Ez az eszköz létrehoz egy új osztályt, amely név nevű tartománytulajdonságsal rendelkezik. A Is Element Name és a Is Moniker Key tulajdonságai ennek a tartományi tulajdonságnak true-re vannak inicializálva.

  • -vagy-

    Hozzon létre egy öröklési kapcsolatot a tartományosztályból egy másik osztályhoz, amely rendelkezik egy monikerkulcs-tulajdonsággel.

Duplikált monikerek elkerülése

Minősített kulcs-monikerek használata esetén előfordulhat, hogy a felhasználó modelljének két eleme ugyanazt az értéket tartalmazza a kulcstulajdonságban. Ha például a DSL-nek van egy személy nevű tulajdonságú osztálya, a felhasználó két elem nevét is beállíthatja azonosra. Bár a modell menthető fájlba, nem tölthető be megfelelően.

A helyzet elkerüléséhez számos módszer létezik:

  • Állítsa be a elemet = true elemnévként a kulcstartomány tulajdonságához. Jelölje ki a tartománytulajdonságot a DSL-definíciós diagramon, majd állítsa be az értéket a Tulajdonságok ablakban.

    Amikor a felhasználó létrehoz egy új osztálypéldányt, ez az érték azt eredményezi, hogy a tartománytulajdonság automatikusan más értéket kap. Az alapértelmezett viselkedés egy számot ad hozzá az osztálynév végéhez. Ez nem akadályozza meg a felhasználót abban, hogy duplikált névre módosítsa a nevet, de segít abban az esetben, ha a felhasználó nem állítja be az értéket a modell mentése előtt.

  • Engedélyezze a validálást a DSL-hez. A DSL Explorerben válassza a Szerkesztő\Ellenőrzés lehetőséget, és állítsa be a Felhasználás... tulajdonságokat true.

    Van egy automatikusan létrehozott ellenőrzési módszer, amely kétértelműségeket keres. A metódus az Load érvényesítési kategóriában található. Így a rendszer figyelmezteti a felhasználót, hogy előfordulhat, hogy nem lehet újra megnyitni a fájlt.

    További információért lásd az Érvényesítést Domain-Specific nyelven.

A moniker elérési útjai és minősítői

A minősített kulccsal rendelkező moniker a moniker kulccsal végződik, és a beágyazási fában a szülő monikerével van előtaggal elnevezve. Ha például egy album neve a következő:

<albumMoniker title="/My Favorites/Jazz after Teatime" />

Ezután az album egyik dala a következő lehet:

<songMoniker title="/My Favorites/Jazz after Teatime/Hot tea" />

Ha azonban az albumokra azonosító alapján hivatkozunk, a nevek a következők:

<albumMoniker Id="77472c3a-9bf9-4085-976a-d97a4745237c" />
<songMoniker title="/77472c3a-9bf9-4085-976a-d97a4745237c/Hot tea" />

Figyelje meg, hogy mivel a GUID egyedi, soha nem szerepel előtagként a szülője monikeréhez.

Ha tudja, hogy egy adott tartománytulajdonság mindig egyedi értékkel fog rendelkezni egy modellben, beállíthatja a "Is Moniker Qualifier"-t "true"-ra ennél a tulajdonságnál. Emiatt a rendszer minősítőként használja a szülő monikerének használata nélkül. Ha például Is Moniker Qualifier és Is Moniker Key értékét is beállítja az Album osztály Címtartomány tulajdonságához, a modell neve vagy azonosítója nem használatos az Album és a beágyazott gyermekek monikereiben:

<albumMoniker name="Jazz after Teatime" />
<songMoniker title="/Jazz after Teatime/Hot tea" />

Az XML szerkezetének testreszabása

Az alábbi testreszabások végrehajtásához bontsa ki az Xml szerializálási viselkedési csomópontot a DSL Explorerben. Egy tartományosztály alatt bontsa ki az Elemadat csomópontot az ebben az osztályban forrásként használt tulajdonságok és kapcsolatok listájának megtekintéséhez. Válasszon ki egy kapcsolatot, és módosítsa a beállításokat a Tulajdonságok ablakban.

  • Állítsa be az Elem kihagyása értéket igazra a forrásszerepkör-csomópont kihagyása érdekében, így csak a célelemek listája marad meg. Ne állítsa be ezt a beállítást, ha több kapcsolat van a forrás- és célosztályok között.

    <familyTreeModel ...>
      <!-- The following node is omitted by using Omit Element: -->
      <!-- <people> -->
        <person name="Henry VIII" .../>
        <person name="Elizabeth I" .../>
      <!-- </people> -->
    </familyTreeModel>
    
  • Állítsa be a Teljes űrlap-et a célcsomópontoknak a kapcsolatpéldányokat képviselő csomópontokba történő beágyazásához. Ez a beállítás automatikusan be van állítva, amikor tartománytulajdonságokat ad hozzá egy tartománykapcsolathoz.

    <familyTreeModel ...>
      <people>
        <!-- The following node is inserted by using Use Full Form: -->
        <familyTreeModelHasPeople myRelationshipProperty="x1">
          <person name="Henry VIII" .../>
        </familyTreeModelHasPeople>
        <familyTreeModelHasPeople myRelationshipProperty="x2">
          <person name="Elizabeth I" .../>
        </familyTreeModelHasPeople>
      </people>
    </familyTreeModel>
    
  • Állítsa be Ábrázolás = Elem, hogy a tartománytulajdonságokat ne attribútumértékként, hanem elemként mentse.

    <person name="Elizabeth I" birthYear="1533">
      <deathYear>1603</deathYear>
    </person>
    
  • Az attribútumok és kapcsolatok szerializálási sorrendjének módosításához kattintson a jobb gombbal az Elemadatok csoportban található elemre, és használja a Feljebb vagy lefelé menüparancsokat.

Fő testreszabás programkód használatával

Lecserélheti az alkatrészeket vagy az összes szerializálási algoritmust.

Javasoljuk, hogy tanulmányozza a kódot Dsl\Generated Code\Serializer.cs és SerializationHelper.cs.

Egy adott osztály szerializálásának testreszabása

  1. Az beállítást a XML szerializálási viselkedésalatt az adott osztály csomópontjában Egyénire állították.

  2. Alakítsa át az összes sablont, hozza létre a megoldást, és vizsgálja meg az ebből eredő fordítási hibákat. Az egyes hibákhoz közeli megjegyzések ismertetik, hogy milyen kódot kell megadnia.

Saját szerializálás végrehajtása a teljes modellhez

  1. A Dsl\GeneratedCode\SerializationHelper.cs-ben lévő metódusok felülbírálása

Jegyzet

A Visual Studio 2022 17.13-tól kezdve az alapértelmezett szerializálási megvalósítás már nem támogatja a BinaryFormatter használatával történő egyéni adattípusok szerializálását vagy deszerializálását a BinaryFormatter biztonsági kockázatai miatt (,).

Ha bármely tartománytulajdonsághoz egyéni adattípust használ, felül kell bírálnia a szerializálási módszereket a SerializationHelper osztályban, vagy implementálnia kell egy TypeConverter-et, amely képes az egyes egyéni adattípusokat sztringgé alakítani, és fordítva.

Bár biztonsági okokból nem javasoljuk a BinaryFormatter használatát, ha fenn kell tartania a BinaryFormatter szerializálást használó régebbi modellekkel való kompatibilitást, implementálhat egy TypeConverter-t, amely deszerializálja a bináris adatokat. A kompatibilitás implementálásához a következő kódrészlet szolgál sablonként:

class MyCustomDataTypeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is string text)
        {
            // First, try to parse the string as if it were returned by MyCustomDataType.ToString().
            if (MyCustomDataType.TryParse(text, out var custom))
                return custom;

            // Fall back to trying to deserialize the old BinaryFormatter serialization format.
            var decoded = Convert.FromBase64String(text);
            using (var memory = new MemoryStream(decoded, false))
            {
                var binaryFormatter = new BinaryFormatter();
                return binaryFormatter.Deserialize(memory) as MyCustomDataType;
            }
        }

        return base.ConvertFrom(context, culture, value);
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(string) && value is MyCustomDataType custom)
            return custom.ToString();

        return base.ConvertTo(context, culture, value, destinationType);
    }
}

// ...

[TypeConverter(MyCustomDataTypeConverter)]
class MyCustomDataType
{
    // ...
}

Az XML szerializálási viselkedésének beállításai

A DSL Explorerben az Xml szerializálási viselkedés csomópontja minden tartományosztályhoz, kapcsolathoz, alakzathoz, összekötőhöz és diagramosztályhoz tartalmaz egy gyermekcsomópontot. Az egyes csomópontok alatt található az adott elemhez tartozó tulajdonságok és kapcsolatok listája. A kapcsolatok önállóan és a forrásosztályaikban is képviselve vannak.

Az alábbi táblázat összefoglalja a DSL-definíció ezen szakaszában megadható beállításokat. Minden esetben jelöljön ki egy elemet a DSL Explorerben, és adja meg a beállításokat a Tulajdonságok ablakban.

Xml-osztály adatai

Ezek az elemek Xml szerializálási viselkedés\Osztályadatokterületen találhatók a DSL Explorerben.

Ingatlan Leírás
Megvan az egyéni elemelemek terve Ha igaz, azt jelzi, hogy a tartományosztály egyéni elemsémával rendelkezik
Egyéni Állítsa az értéket Igaz, ha saját szerializálási és deszerializálási kódot szeretne írni ehhez a domain osztályhoz.

Hozza létre a megoldást, és vizsgálja meg a hibákat a részletes utasítások felderítéséhez.
Tartományosztály Tartományosztály, amelyre ez az osztályadatcsomópont vonatkozik. Írásvédett.
Elem neve Az osztály elemeinek XML-csomópontjának neve. Az alapértelmezett érték a tartományosztálynév kisbetűs verziója.
Azonosító attribútum neve A hivatkozást tartalmazó monikerelemekben használt attribútum neve. Ha üres, a rendszer a kulcstulajdonság vagy -azonosító nevét használja.

Ebben a példában ez a "név": <personMoniker name="/Mike Nash"/>
Azonosítóelem neve Az osztály elemeire hivatkozó monikerekhez használt xml-elem neve.

Az alapértelmezett érték a "Moniker" utótaggal ellátott osztálynév kisbetűs verziója. Például personMoniker.
A moniker típusának neve Az osztály elemeihez tartozó hivatkozó nevek számára létrehozott xsd típus neve. Az XSD a(z) Dsl\Generated Code\*Schema.xsd-ben található
Szerializálási azonosító Ha igaz, a GUID elem szerepel a fájlban. A értékétIgaz értékre kell állítani, ha nincs olyan tulajdonság, amely A Moniker-kulcs, és a DSL az osztály hivatkozási kapcsolatait határozza meg.
Típus neve A kijelölt tartományosztály xsd fájljában létrehozott xml-típus neve.
Jegyzetek Az elemhez társított nem hivatalos jegyzetek

Xml-tulajdonságadatok

Az xml tulajdonságcsomópontok az osztálycsomópontok alatt találhatók.

Ingatlan Leírás
Tartománytulajdonság Az xml-szerializálás konfigurációs adatainak alapjául szolgáló tulajdonság. Írásvédett.
A Moniker kulcs Ha az érték a True értékre van állítva, a rendszer a tulajdonságot használja a tartományosztály példányait hivatkozó monikerek létrehozásához.
Moniker-minősítő Ha az érték Trueértékre van állítva, a tulajdonság a minősítő monikerekben való létrehozásához használatos. Ha hamis, és a szerializálási azonosító nem igaz erre a tartományosztályra, a monikereket a beágyazási fa szülőelemének monikerje minősíti.
Képviselet Ha az érték attribútumértékre van állítva, akkor a tulajdonság xml-attribútumként szerializálva lesz; ha az érték Elemértékre van állítva, akkor elemként szerializálva van; ha az érték Mellőzésértékre van állítva, akkor nincs szerializálva.
XML-név A tulajdonságot képviselő XML-attribútumhoz vagy elemhez használt név. Alapértelmezés szerint az érték a tartománytulajdonság nevének kisbetűs verziója.
Jegyzetek Az elemhez társított nem hivatalos jegyzetek

Xml-szerepkör adatai

A szerepkör-adatcsomópontok a forrásosztály csomópontjai alatt találhatók.

Ingatlan Leírás
Egyéni moniker Ha saját kódot szeretne használni a kapcsolaton áthaladó monikerek generálásához és feloldásához, állítsa ezt igaz értékre.

Részletes útmutatásért hozza létre a megoldást, majd kattintson duplán a hibaüzenetekre.
Tartománykapcsolat Meghatározza azt a kapcsolatot, amelyre ezek a beállítások vonatkoznak. Csak olvasható.
Elem kihagyása Ha igaz, a forrásszerepkörnek megfelelő XML-csomópont ki lesz hagyva a sémából.

Ha a forrás- és célosztályok között több kapcsolat is van, ez a szerepkör-csomópont megkülönbözteti a két kapcsolathoz tartozó kapcsolatokat. Ezért javasoljuk, hogy ebben az esetben ne állítsa be ezt a beállítást.
Szerepkörelem neve Megadja a forrásszerepkörből származtatott XML-elem nevét. Az alapértelmezett érték a szerepkörtulajdonság neve.
Teljes űrlap használata Ha igaz, minden célelem vagy moniker egy, a kapcsolatot képviselő XML-csomópontba kerül. Ezt igaz értékre kell állítani, ha a kapcsolatnak saját tartománytulajdonságai vannak.