Ik zit met een design probleempje. Wanneer ik een object wil beheren geef ik deze vaak mee aan een beheersform (zie code).
Nu is dit niet zo spannend maar ik krijg problemen als ik ook validatie toevoeg in het form. Ik maak gebruik van Fluent Validation. Dit framework valideert objecten door instanties mee te geven. Ook dit is niet echt spannend.
De problemen waar ik mee in mijn maag zit zijn alsvolgt:
Vóórdat ik ga valideren update ik de object instantie in het beheersform met de ingevulde waardes op het scherm. Als de validatie NIET goed gaat en ik druk op cancel dan zijn de waardes natuurlijk nog steeds geset omdat het object als reference is doorgegeven aan het beheersform. Als ik dan op cancel druk, dan is het object uiteraard niet meer in zijn oorspronkelijke staat omdat het kortgeleden ervoor is geset om validatie te kunnen uitvoeren.
C#:
1
2
3
4
5
6
7
8
| Person person = new Person("Voornaam", "Achternaam"); formPerson form = new formPerson(person); if (form.ShowDialog() == DialogResult.OK) { // OK button has been pressed } else { // Canceled } |
Nu is dit niet zo spannend maar ik krijg problemen als ik ook validatie toevoeg in het form. Ik maak gebruik van Fluent Validation. Dit framework valideert objecten door instanties mee te geven. Ook dit is niet echt spannend.
C#:
1
2
3
| Person person = new Person("Voornaam", "Achternaam"); PersonValidator validator = new PersonValidator(); ValidationResult results = validator.Validate(person); |
De problemen waar ik mee in mijn maag zit zijn alsvolgt:
Vóórdat ik ga valideren update ik de object instantie in het beheersform met de ingevulde waardes op het scherm. Als de validatie NIET goed gaat en ik druk op cancel dan zijn de waardes natuurlijk nog steeds geset omdat het object als reference is doorgegeven aan het beheersform. Als ik dan op cancel druk, dan is het object uiteraard niet meer in zijn oorspronkelijke staat omdat het kortgeleden ervoor is geset om validatie te kunnen uitvoeren.
- Ik kan een clone maken waar de waardes op geset gaan worden. Tevens zal ik dan de validatie op de clone uitvoeren. Ik kan een ICloneable interface implementeren alleen moet ik dan handmatig aangeven wat ik wel en niet wil clonen. Ook ga je in de toekomst problemen krijgen als je een class uitbreidt en je vergeet de clone uit te breiden. Geen mooie oplossing naar mijn idee.
- Ik kan gebruik maken van reflectie bij het clonen maar naar mijn idee maakt dit alles ook niet veel duidelijker en het wordt gevoeliger voor fouten en performance issues. Ook niet echt een oplossing dus.
- Ik kan het gecancelde object opnieuw ophalen uit de database maar bij complexere objecten en relaties krijg je hier misschien problemen mee (parent / child relaties waarvan de referentie dezelfde hoort te zijn maar bij een refresh niet meer gelijk is omdat de ene referentie een gerefreshed object bevat terwijl de andere nog de orginele is). Geen idee of dit ook daadwerkelijk een probleem kan gaan worden.
- Ik valideer alleen de input zonder het object daadwerkelijk te setten. Het nadeel hiervan is dat ik mijn logica niet kan hergebruiken wat onderhoudbaarheid niet ten goede komt.
PSN: Norfirin