Toon posts:

[.NET] Serialization

Pagina: 1
Acties:

Verwijderd

Topicstarter
Tweakers,

Ik heb een mooi 4 lagen model gemaakt,

-User interface (webpagina's)
-Interfaces
-Business logic
-Data logic
-Data helper (.NET application block)

Mijn objecten in de business logic laag hebben o.a. methodes uit de abstracte basis classe genaamd "Opslaan" en "Verwijderen". Deze methoden geven de aangepaste of nieuwe properties door aan de data logic layer.

Omdat de data logic layer niet "op de hoogte" mag zijn van de business layer objecten wil ik niet het object zelf doorgeven aan een update of insert methode van de data layer.

In plaats daarvan heb ik ervoor gekozen om de objecten in de business layer serializable te maken. De geserialisde XML verstuur ik dan naar methoden in de data logic layer. Deze is dan verantwoordelijk voor de verwerking richting database.

Ik erf mijn objecten nu mooi van de ISerializable classe. Met tags als [XmlElement()] en [XmlIgnoreAttribute()] bepaal ik precies hoe de opgeleverde XML er uit gaat zien. Dat werkt ook erg mooi. Mijn abstracte basisclasse bevat nu de methode "OphalenXML" die van alle afgeleide serializable classes mooi de properties als XML retourneren.

Het probleem

Het probleem is alleen dat ik alleen het volgende in de XML heb staan:
<PropertyNaamTag>PropertyWaarde</PropertyNaamTag>

Ik ben hier kwijt om welk type het gaat, een int, long, string, etc. Nogal lastig om daar nog een nette insert of update van de genereren. Ik heb gezocht naar een soort van [XmlElementType()] of dergelijke tag die het type mee zou kunnen geven. Deze lijkt niet te bestaan.

Natuurlijk zorg je normaal gesproken voor een XML schema. De standaard serialize methode kan deze alleen na mijn weten en onderzoek niet genereren. Ik ben nu dus hard op zoek naar een manier om toch type informatie met de geserialisde properties mee te geven.

Hopelijk hebben jullie hier ook ideën over... :)

  • tijn
  • Registratie: Februari 2000
  • Laatst online: 12:24
Verwijderd schreef op 11 juni 2004 @ 10:20:
Omdat de data logic layer niet "op de hoogte" mag zijn van de business layer objecten wil ik niet het object zelf doorgeven aan een update of insert methode van de data layer.
Mag ik vragen waarom niet?

Cuyahoga .NET website framework


Verwijderd

Topicstarter
tijn schreef op 11 juni 2004 @ 10:26:
[...]

Mag ik vragen waarom niet?
In eerste instantie omdat het een eis van de klant is, ten tweede omdat ze de datalaag en businesslaag op verschillende PC's willen draaien en omdat ze ook een webservice willen gebruiken die de geserialisde business layer data objecten door kan gaan geven.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Verwijderd schreef op 11 juni 2004 @ 10:41:
[...]
In eerste instantie omdat het een eis van de klant is, ten tweede omdat ze de datalaag en businesslaag op verschillende PC's willen draaien en omdat ze ook een webservice willen gebruiken die de geserialisde business layer data objecten door kan gaan geven.
Pas maar op dat er dan geen verouderde business objecten bij een ander in het geheugen blijven hangen dan. Verder is het nogal 'vreemd' dat je objecten op deze manier wilt gaan serializen en denk ook eerder dat er sprake is van onkunde.

En hoe bedoel je dat de datalayer laag niet op de hoogte mag zijn van de business layer objecten? Ik neem aan dat de businesslayer laag gewoon alle domein objecten bevat (Klant, Order) en de data laag zal toch echt die object van en naar een database moeten kunnen verplaatsen.

Ik snap dus jullie opsplitsing niet? Met de datalaag bedoelen jullie de domein objecten en met de business laag de bedrijfslogica laag? Vreemd omdat zo van elkaar te scheiden. En als je toch goed wilt scheiden moet je het al helemaal niet zo willen oplossen maar werken met ruleengines (business rule engines/bizztalk bv).

[ Voor 35% gewijzigd door Alarmnummer op 11-06-2004 10:49 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:33
Alarmnummer schreef op 11 juni 2004 @ 10:45:
[...]
En hoe bedoel je dat de datalayer laag niet op de hoogte mag zijn van de business layer objecten? Ik neem aan dat de businesslayer laag gewoon alle domein objecten bevat (Klant, Order) en de data laag zal toch echt die object van en naar een database moeten kunnen verplaatsen.
Dat is toch logisch? Je DAL hoeft niets te weten van je business layer. Omgekeerd echter wel: je Business Objecten zullen gebruik maken van DAL objecten om data te gaan bewaren.

https://fgheysels.github.io/


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

whoami schreef op 11 juni 2004 @ 10:56:
[...]
Dat is toch logisch? Je DAL hoeft niets te weten van je business layer. Omgekeerd echter wel: je Business Objecten zullen gebruik maken van DAL objecten om data te gaan bewaren.
Je DAL laag moet weten hoe die domein objecten eruit zien, dus de DAL laag moet wel op de hoogte zijn van de structuur van domein objecten. De laag waarin de domein objecten hun werk doen, moet op de hoogte zijn van de DAL omdat je anders niet kan saven. Dat je met allerlei mooie abstract factories een ontkoppeling van implementaties kan aanbieden is een 2e.

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Je maakt een klassieke fout. ISerializable heeft niets te maken met XML serialization. XML Serialization wordt gedaan door de XmlSerializer die gebruik maakt van de IXmlSerializable interface en die is undocumented. De reden hiervoor is dat de XmlSerializer verschrikkelijk crappy geimplementeerd is en alles dat die interface implementeert voor een Dataset aanziet. (ja, echt)

ISerializable wordt uitgevoerd door de binary formatter, soap formatter of je eigen formatter. XmlSerializer is verder erg beperkt: het kan niet omgaan met event handlers in je class, wil perse een empty constructor, crasht bij cyclic references (essentieel vaak bij BL components: customer.Orders bevat Order objects die via hun .Customer property verwijzen naar dezelfde Customer) en kan niet omgaan met interface typed members/properties. Verder genereert het eerst code, die het compileert en dan executeert om de XML te produceren. Dit is met een hoge load wellicht sneller maar bij af en toe gebruik retetraag.

Ik heb zelf XmlSerializer functionaliteit geschreven voor mn entities en entity collections. Die genereert XML met type info in attributes in the XML, kan cyclic references aan en genereert geen code alvorens bezig te gaan. Op zich is het niet zo moeilijk, 500-1000 regels code dan ben je er wel.
Alarmnummer schreef op 11 juni 2004 @ 10:59:
Je DAL laag moet weten hoe die domein objecten eruit zien, dus de DAL laag moet wel op de hoogte zijn van de structuur van domein objecten. De laag waarin de domein objecten hun werk doen, moet op de hoogte zijn van de DAL omdat je anders niet kan saven. Dat je met allerlei mooie abstract factories een ontkoppeling van implementaties kan aanbieden is een 2e.
Niet iedereen is overtuigd van het gelijk van Evans/Fowler cs. en niet iedereen werkt dus met domain objects in de DAL die opgevrolijkt worden met BL code in de BL. Sommigen kiezen bv voor een meer service oriented / manager object benadering, en zien meer in bv het centreren van functionaliteit in een process dat entities consumeert dan dat je de functionaliteit verspreidt over meerdere entities en daardoor in feite je BL versnippert.

Als ik jouw verhaal zo lees creeer je een berg overhead waar je u tegen zegt om die cyclic reference maar in stand te houden, ipv een stap terug te doen en eens nuchter na te denken wat je nu eigenlijk aan het doen bent.

[ Voor 27% gewijzigd door EfBe op 11-06-2004 11:13 ]

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:33
Alarmnummer schreef op 11 juni 2004 @ 10:59:
[...]

Je DAL laag moet weten hoe die domein objecten eruit zien, dus de DAL laag moet wel op de hoogte zijn van de structuur van domein objecten. De laag waarin de domein objecten hun werk doen, moet op de hoogte zijn van de DAL omdat je anders niet kan saven. Dat je met allerlei mooie abstract factories een ontkoppeling van implementaties kan aanbieden is een 2e.
Creeër jij dan geen circulaire reference tussen je DAL en BL als beide van elkaar weet moeten hebben?

Als je DAL weet heeft van je BL, dan is je DAL toch te 'tightly coupled' met je BL ?
Als je BL dan wijzigt, zal je je DAL ws ook moeten wijzigen.

Ik heb in dit ook te maken met DAL en BL objecten, waar ik verschillende types v. databanken moet kunnen benaderen.
Daar heb ik eigenlijk een DAL class, die alle methods bevat om databank operaties op uit te voeren. Een andere class (kan je die class een Business Class noemen?) roept dan de juiste method op van die DAL class.
Echter, ook daar weet m'n DAL class (de class met de DB methods dus, die eigenlijk stateless is) van m'n die andere objecten, en eigenlijk ben ik daar niet zo tevreden over. (Zie dat topic voor meer uitleg, en ook voor commentaar).

[ Voor 32% gewijzigd door whoami op 11-06-2004 11:25 ]

https://fgheysels.github.io/


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Alarmnummer schreef op 11 juni 2004 @ 10:45:
En hoe bedoel je dat de datalayer laag niet op de hoogte mag zijn van de business layer objecten? Ik neem aan dat de businesslayer laag gewoon alle domein objecten bevat (Klant, Order) en de data laag zal toch echt die object van en naar een database moeten kunnen verplaatsen.
Mja. Je creeert toch echt dat probleem zelf hoor. Je BL is een consumer van de DAL, niet deel van de DAL. De DAL krijgt gewoon opdracht entities te manipuleren. Het is echt niet verplicht die entities uit te breiden in de BL en DUS dat je de DAL daarvan op de hoogte moet houden, sterker, dat is extra complexiteit die nergens voor nodig is. Software development is echt zo simpel als 1 2 3. Alleen vinden veel mensen telkens weer een manier om het zo complex mogelijk te maken. :)
Ik snap dus jullie opsplitsing niet? Met de datalaag bedoelen jullie de domein objecten en met de business laag de bedrijfslogica laag? Vreemd omdat zo van elkaar te scheiden. En als je toch goed wilt scheiden moet je het al helemaal niet zo willen oplossen maar werken met ruleengines (business rule engines/bizztalk bv).
Mja, ik snap de versnippering van functionaliteit over meerdere classes niet. Evans heeft zelf aangegeven dat het wenselijk is een vertaalmanier te vinden tussen functionaliteitsbeschrijvingen en domain classes. Lijkt me een middel om een symptoom te bestrijden van de methodiek zelf, ipv de methodiek eens aan een kritische blik te onderwerpen.

Toch gek dat met 20 jaar oude theorie je de problemen die jij schetst niet hebt, sterker nog, het wordt er alleen maar simpeler op, wat, sorry, alleen maar voordelen heeft. Maar goed, het is jouw tijd natuurlijk ;)

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • tijn
  • Registratie: Februari 2000
  • Laatst online: 12:24
whoami schreef op 11 juni 2004 @ 10:56:
[...]

Dat is toch logisch? Je DAL hoeft niets te weten van je business layer.
Je DAL zal toch op zijn minst wel het type moeten weten van de business objecten die je wilt opslaan? Of gebruikt de DAL datasets/datatables in de interface?

Cuyahoga .NET website framework


  • EfBe
  • Registratie: Januari 2000
  • Niet online
whoami schreef op 11 juni 2004 @ 11:20:
Creeër jij dan geen circulaire reference tussen je DAL en BL als beide van elkaar weet moeten hebben?

Als je DAL weet heeft van je BL, dan is je DAL toch te 'tightly coupled' met je BL ?
Als je BL dan wijzigt, zal je je DAL ws ook moeten wijzigen.
Er is IMHO geen 'dal' en 'bl' in het domain model maar kortweg een bak met 'domain objects'. De BL zit in de domain objects en de dal bestaat uit een dunne laag functionaliteit die die domain objects savet/laadt. Het is allemaal veel platter (in tiers)

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:33
tijn schreef op 11 juni 2004 @ 11:25:
[...]

Je DAL zal toch op zijn minst wel het type moeten weten van de business objecten die je wilt opslaan? Of gebruikt de DAL datasets/datatables in de interface?
IMO gebruikt je Business Laag je DAL objecten, en niet omgekeerd:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class BusinessObjectKlant
{
    public void Save()
    {
         if( _klantId == -1 ) 
         {
              DALObjectKlant.InsertKlant ( .... );
         }
    }
}

class DALObjectKlant
{
    public static InsertKlant ( string naam, string adres, out int klantId )
    {
          // insert klant into DB
    }
}

https://fgheysels.github.io/


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:33
EfBe schreef op 11 juni 2004 @ 11:26:
[...]

Er is IMHO geen 'dal' en 'bl' in het domain model maar kortweg een bak met 'domain objects'. De BL zit in de domain objects en de dal bestaat uit een dunne laag functionaliteit die die domain objects savet/laadt. Het is allemaal veel platter (in tiers)
Bedoel je dan eerder zoiets:

code:
1
2
3
public class Klant
{
}


En
code:
1
2
3
4
5
6
7
8
9
10
11
public class KlantDBSpul
{
     public static Klant LoadKlant ( int klantId )
     {
             // Load klant-info from DB
             return new Klant ( klantNaam, adres, ... );
     }
     public static void SaveKlant( Klant k )
     {
     }
}

[ Voor 4% gewijzigd door whoami op 11-06-2004 11:30 ]

https://fgheysels.github.io/


Verwijderd

Topicstarter
Ik hoop e.e.a. nog iets te verduidelijken:

Onze datalaag levert enerzijds gewoon datasets op wanneer bijvoorbeeld de business laag hier om vraagt. De businesslaag vraag bijvoorbeeld een dataset met gebruikersgegegevens. Hij (de business laag) is vervolgens verantwoordelijk voor de omzetting naar een gebruikers- object.

Dit object bevat alle eigenschappen van de gebruiker (naam, adres, etc), aangevuld met enkele methodes die worden geimplementeerd uit een abstracte classe, o.a. opslaan, verwijderen en nieuw.

Als de methode "opslaan" wordt aangeroepen gaat het business object afhankelijk van een status "nieuw" of "bewerkt" weer aankloppen bij de datalaag om de methode nieuw of bewerk aan te roepen. Omdat wij de datalaag geen business unit object door willen / mogen geven kan je dit natuurlijk doen met een lading parameters. Er wordt echter gekozen voor een naar XML geserialisde representatie van het business unit object.

De datalaag heeft nu alle properties als XML en weet verder niks af van het object. De methodes zijn ook allemaal weg. Hij weet nu alleen te weinig. Er is namelijk geen info meer beschikbaar over het type property (datum, string of long) waardoor posten naar de database weer onmogelijk wordt.

Als we bij het serializen nou ook nog per property het datatype mee kunnen geven, of kunnen serializen met een XML schema is het probleem opgelost.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Ik dacht dat jullie met data objecten jullie dal laag bedoelden, maar het zijn gewoon jullie domein objecten. Dus vandaar de miscommunicatie.

Verder schrijft fowler ook zeker niet voor dat domein objecten altijd moeten bestaan uit data en logica.

  • tijn
  • Registratie: Februari 2000
  • Laatst online: 12:24
whoami schreef op 11 juni 2004 @ 11:27:
[...]


IMO gebruikt je Business Laag je DAL objecten, en niet omgekeerd:

code:
1
2
3
4
5
6
7
class DALObjectKlant
{
    public static InsertKlant ( string naam, string adres, out int klantId )
    {
          // insert klant into DB
    }
}
zou

code:
1
2
3
4
public static InsertKlant(Klant klant)
{
    // insert klant into DB
}

niet wat eleganter en onderhoudsvriendelijker zijn?

Cuyahoga .NET website framework


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:33
EfBe schreef op 11 juni 2004 @ 11:09:
Je maakt een klassieke fout. ISerializable heeft niets te maken met XML serialization. XML Serialization wordt gedaan door de XmlSerializer die gebruik maakt van de IXmlSerializable interface en die is undocumented. De reden hiervoor is dat de XmlSerializer verschrikkelijk crappy geimplementeerd is en alles dat die interface implementeert voor een Dataset aanziet. (ja, echt)
Ik heb dit artikel zelf nog niet gelezen, maar het kan best interessant zijn.

https://fgheysels.github.io/


  • tijn
  • Registratie: Februari 2000
  • Laatst online: 12:24
Verwijderd schreef op 11 juni 2004 @ 11:31:
Als we bij het serializen nou ook nog per property het datatype mee kunnen geven, of kunnen serializen met een XML schema is het probleem opgelost.
Aangezien jullie toch al datasets gebruiken, zou je niet gewoon een dataset kunnen gebruiken voor het opslaan? Welliswaar een botte bijl methode, maar al je eisen zijn er mee in te willigen (als ik goed gelezen heb tenminste :).

Cuyahoga .NET website framework


  • EfBe
  • Registratie: Januari 2000
  • Niet online
whoami schreef op 11 juni 2004 @ 11:36:
Ik heb dit artikel zelf nog niet gelezen, maar het kan best interessant zijn.
Nou, wat ze ook schrijven, de serialization PM zei op de DOTNET mailing list letterlijk dat de code 'broken' was, en dus IXmlSerializable niet geimplementeerd kon worden om zo je classes met de XmlSerializer te laten werken. Het werkt pas in Whidbey (i.e.: over een jaar oid ;)
Bedoel je dan eerder zoiets:
Nee, ik bedoel dat 'Klant' de class is waar alle BL van 'klant' in zit en die je aan een generic persister geeft die dmv bv een xml file de data in 'klant' kan persisten.

[ Voor 18% gewijzigd door EfBe op 11-06-2004 12:19 ]

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:33
EfBe schreef op 11 juni 2004 @ 12:18:
[...]


Nee, ik bedoel dat 'Klant' de class is waar alle BL van 'klant' in zit en die je aan een generic persister geeft die dmv bv een xml file de data in 'klant' kan persisten.
Dit snap ik niet zo goed. Wat is de rol van die xml file ?

Wat is er mis met deze aanpak?

https://fgheysels.github.io/


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:33
Ik ga trouwens deze artikelen eens doornemen.
Eens kijken hoe ze het daar opzetten.

https://fgheysels.github.io/


  • EfBe
  • Registratie: Januari 2000
  • Niet online
whoami schreef op 11 juni 2004 @ 12:24:
[...]


Dit snap ik niet zo goed. Wat is de rol van die xml file ?
die mapt class fields op table fields of omgekeerd :)
Wat is er mis met deze aanpak?
Niets, het is alleen erg specifiek per class, terwijl die logica ook generiek kan worden gemaakt (met bv een hele dunne specifieke class per entity class)

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:33
EfBe schreef op 11 juni 2004 @ 12:58:
[...]

die mapt class fields op table fields of omgekeerd :)
Dan heb je 1 class met static methods, update, delete, select en je geeft je object en een xml-file door ?
Op zich niet zo'n slecht idee, maar dan heb je wel een hele hoop xml-files die je moet onderhouden, en wat als er zo'n xml file verschwunden is?

https://fgheysels.github.io/


Verwijderd

Topicstarter
Overigens ook een erg nuttige link:
URL=http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/BOAGag.asp
Modified=30847AB4254AC40116

  • EfBe
  • Registratie: Januari 2000
  • Niet online
whoami schreef op 11 juni 2004 @ 13:20:
Dan heb je 1 class met static methods, update, delete, select en je geeft je object en een xml-file door ?
Op zich niet zo'n slecht idee, maar dan heb je wel een hele hoop xml-files die je moet onderhouden, en wat als er zo'n xml file verschwunden is?
De xml file komt waar dan ook vandaan, kan gecached worden bv, en bevat de mappings voor alle entities. Ja dat is veel data :) Ook niet mijn idee van het opslaan van mappings hoor, maar dat terzijde ;)

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com

Pagina: 1