I read a bit of DDD and I am confused about how this will fit when using ORM like NHibernate.
Now I have a .NET MVC application with pretty live controllers, and I'm trying to figure out how best to fix it. Moving this business logic to the model layer would be the best way to do this, but I'm not sure how to do it.
My application is configured in such a way that the NHibernate session is managed by the HttpModule (gets the session / transaction from my path), which is used by repositories that return entity objects (Think S # arp arch ... it turns out that they really duplicated a lot of their functionality in this). These repositories are used by DataServices, which right now are wrappers around repositories (a one-to-one mapping between them, for example, UserDataService accepts a UserRepository or actually a repository). These DataServices right now guarantee that data annotations decorating entity classes are checked when saving / updating.
So my objects are actually data objects, but do not contain any real logic. Although I could put some things in entity classes (for example, the Approve method), when this action should perform something like sending an email or touching other unrelated objects or, for example, checking to see, there are users who have same email before approval, etc., then entities will need access to other repositories, etc. Entering data using IoC will not work with NHibernate, so you will have to use the factory I assume to get them. I don’t understand how you would mock tests.
So the next most logical way to do this, I think, would be to essentially have a service on the controller and extract all the work currently being done on the controller into the methods in each service. I would think that this breaks down with the idea of DDD, though, since the logic is now no longer contained in the real objects of the model.
Another way to consider this, I think, is that each of these services forms a single model with the data object that it works with (separating the data storage fields and the logic that runs on it), but I just wanted to see what others do to solve the problem of a "live controller" using DDD using ORM, for example NHibernate, which works by returning populated data objects and a repository model.
Update I think my problem is how I look at this: NHibernate seems to put business objects (entities) at the bottom of the stack, after which the repositories act. Repositories are used by services that can use several repositories and other services (email, file access) to perform actions. Ie: Application> Services> Repositories> Business objects
The pure DDD approach that I read seems to reflect an Active Record offset where CRUD functions exist in business objects (I call User.Delete directly instead of Repository.Delete from the service) and the actual business object handles the logic of the things that need to be done in this case (for example, by emailing the user and deleting files belonging to the user, etc.). That is, Application> (Services)> Business Objects> Repositories
With NHibernate, it seems to me that it would be better to use the first approach, given the functions of NHibernate, and I am looking for confirmation according to my logic. Or, if I'm just confused, some clarification on how this tiered approach should work. I understand that if I have an Approve method that updates the User model, it saves and, say, sends several messages to several people that this method should go to the User object object, but to ensure proper IoC so that I can enter messagingService , I need to do this at my service level, and not at the User object.
From the point of view of the “multiple UI”, it makes sense, since the logic of doing things is taken out of my user interface (MVC) level and placed in these services ... but I am essentially just factoring the logic from another class, instead of doing it directly in the controller, and if I don’t have any other user interface, I just trade the “fat controller” for the “thick service”, since the service is essentially going to encapsulate a method for each controller action to make it work.