C # architecture question

I am designing a project where all the main components have one common DomainObject (yes, I stole the term from the O / RM world, but its not really an O / RM project). DomainObject maintains object change state (dirty / clean) and allows itself to be rolled back or committed (AcceptChanges (), RejectChanges ()). When AcceptChanges () is called on an object, it fires an event and this event triggers writing hte values ​​to the underlying data store. In addition, it passes a parameter to cancel saving to the event.

1) An instance of the class (DomainObject) is created and its properties changed.
2) Classroom.AcceptChanges () is called, calling OnAcceptEvent and passing in DomainObjectChangeEventArgs that contain a boolean property called Cancel
3) If not canceled by the event, the changes are accepted and the state of the hte class is updated.
4) Then the project calls AcceptChanges on any internal properties that are also DomainObjects like Student.
5) Each student fires OnAcceptEvent passing DomainObjectChangeEventArgs ... etc.

Now, asking the community as a whole:

A) You have a cancellation indicator in your AcceptEvent class to stop the whole process, causing it to no longer evaluate and possibly accept no students, or you would code Cancel to just apply to the class. b) Can the Cancellation indicator of any student be expected to stop processing on any additional students?

My initial thought is that the cancellation indicator in a Classroom event should stop the entire process, thus ensuring that pre-accepted classroom state and all students are properly saved without incurring transaction overhead. But I'm not sure if I'm right.

What would you do?

0


a source to share


4 answers


I would call the event CanSave, which returns enum {OK, Cancel}. Before I left anything, I would query the entire object graph looking for cancel. Each object can check itself and undo if it is not currently in a steady state ... drops most, but not all, rollbacks.

But what can you do about canceling? One of the main edicts of good software is " Allways allows the user to save work there". Programmers won't abide by an IDE that doesn't keep incompatible source code, so why would you expect your users to put up with it?

Cancellation states should be truly exceptional states ... for example can't write to readonly file -> "Save As" instead? Or a null key field -> "username required".

So what's the alternative? Save in an intermediate format that can store "invalid" data ... as a text file.



Also: I've often thought that database applications were missing a "validate" button to let the user know "is this ok?" without actually doing it.

Just food for thought.

Greetings. Whale.

+1


a source


I think you're on the money.



+1


a source


Yes, you should undo the entire process anyway. You are calling accept on the root object graph, so the consumer's expectation is that the entire graph is saved. I would treat it as all or nothing.

+1


a source


If we say that adding students to your class only changes the state of the class (for example, if you keep which student is in the class in a separate table, the number of students a class may have, etc.), then you don't need a student object at all.

If adding to this class or removing from this class changes the class of the student (such as the number of other classes they can accept, etc.), you must propagate and revoke the student objects as well.

+1


a source







All Articles