JanLimpens wrote:
So far my DAO layer works in the same way as you describe, providing the basic CRUD implementation, offered by a base class using generics.
Could I ask what was the reasong that made you make CRUD implementations, and then offer those implementations by a base clase?
Personally, i see no reason for having those, because the CRUD implementation using Castle.ActiveRecord is as simple as saying
Code:
ActiveRecordMediator.Save(object)
ActiveRecordMediator.Delete(object)
ActiveRecordMediator.FindById(id)
and this code is the same for all persisten classes. ActiveRecordMediator just takes any persistent classs and just saves it using current opened session. What else to implement here? Maybe you have specific needs, if yes, would be nice to hear them.
Quote:
I rely on interfaces, so employing IoC, the domain layer is completely ignorant on how data is saved and where it comes from.
jlockwood tells the same:
The interface to the DAOs is agnostic in regard to the actual persistence mechanism and I have an NHibernate-specific implementation of the interface
Why do you actually need persistence agnostic mechanism?
I mean, will you ever change NHibernate to something else? Every data source has very very specific behaviour. Databases have one behaviour, files have other, in-memory persistence the other, etc. In any case, performance is more important than the possibility, that one day for some unknown reason you might want to save all data not to databse, but to file. I putting this very bluntly, don't get offended. I just want to undertand what are your motives.
NHibernate already gives you a database agnostic framework, why do you need to be agnostic from whole persistence mechanism?
Concerning the DAO and Repository, (though I do not get completely what are they exactly), I believe we use neither of them for some specific reasons.
The main is that our desktop app supports many-step undo mechanism. For examle, you can open one window, then another, and so on and so on, up to as many windows as you want (we don't impose any limit), but only when you close the first window, only then all changes go to dabase. You can choose to cancel all changes that you made in other windows (even if you pressed "Save" button), and they will not go to database, and the state will not change.
This we implement very straighforwardly - we have a list of database actions, which are executed only when the first window is saved. When any of the child windows execute save, we do not execute any statements againts the db. And the statements are pretty simple. For example, a database action list might look like this
Code:
ActiveRecordMediator.Save(new Company())
ActiveRecordMediator.Save(Client) // the client is related to company
ActiveRecordMediator.Delete(Client) // the client, which was related to company
ActiveRecordMediator.Save(new Account()) // account for the company
ActiveRecordMediator.Save(new Client()) // client related to compay
ActiveRecordMediator.Save(new Account()) // account related to client
etc
And so on. This has a side effect, that the same object might be saved many time when you actually save the object, but we see it as not a problem. More important is the feature that this way of doing things provides us.
And for this reason we do not need any DAO or any Repository.
Yes, of course, we still have things like ILoadingService, which is a service which knows what associations to load eagerly for specific object, but at the moment every persistent class has only one such service. In future we might expand this interface to support context specific loading services, thought there are ways to automagically retrieve what relations need to loaded eagerly.
Now, to sum up. I believe all this discussion does not help you, JanLimpens :) However, the best part which you can get here is that there is no best solution, and DAO and Repositories are a very very specific for every situtation, so you will have to judge on yourself or with your team together.