Can I use a pure DDD approach with NHibernate?

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.

+6
repository asp.net-mvc nhibernate domain-driven-design
source share
3 answers

In DDD there is no active write slope. Delete is not a method that should be in Entity (for example, User) in DDD.

NHibernate very well supports the DDD approach, due to how completely divorced it remains from your entity classes.

when this action should do something like sending an email, or touching other unrelated objects

One piece of the puzzle that you seem to be missing is domain events. The domain object should not send email directly. This must trigger an event in the Domain for some significant event to occur. Deploy a class whose purpose is to send email when an event occurs and register it to listen to a domain event.

or, for example, check if there are users who have the same e-mail before approval

This should probably be checked before sending the approve call, and not to the function that approves. Push the solution to the level when calling the code.

So, the next most logical way to do this, I would have thought it would essentially have a service on the controller

This can work if it is done with the understanding that the service is the entry point for the client. The purpose of use here is to obtain parameters in the DTO using the interface / client and translate this method into method calls for the object in order to fulfill the required functionality.

+4
source share

A short answer to your question: yes, in fact, I believe that NHibernate improves DDD - you can focus on developing (and changing) your domain model with the first code approach and then easily upgrade portability with NHibernate.

When you create your domain model after DDD, I would expect that most of the business logic that found you in you, MVC controllers, should probably be in your domain objects. In my first attempt to use ASP.NET MVC, I quickly found myself in the same position as you - fat regulators and anemic domain model.

To avoid this, I now take the approach of preserving a rich domain model that implements business logic and uses the MVC model as essentially simple data objects used by my views. This simplifies my controllers - they interact with my domain model and provide simple data objects (from the MVC model) to the views.

Update

The pure DDD approach that I'm reading seems to reflect an Active Record bias ...

For me, an active recording template means that entities are aware of their stability mechanism, and an entity is mapped directly to a database table entry. This is one way to use NHibernate, for example. see Castle Active Record , however I find this a polluting domain of enitities knowledge of its conservation mechanism. Instead, as a rule, I will have an aggregate root repository in my domain model that implements an abstract repository. The abstract repository provides basic CRUD methods, such as:

public IList<TEntity> GetAll() public TEntity GetById(int id) public void SaveOrUpdate(TEntity entity) public void Delete(TEntity entity) 

.. which my specific repositories can complement / expand.

See this NHibernate FAQ post on which I based a lot of my material. Also remember that NHibernate (depending on how you configured your mappings) will allow you to destabilize the full graphic object, i.e. Your aggregate root plus all the objects that depend on it, and as soon as you finish working with it, you can cascade savings through the entire graph of objects, this, of course, is not an active record.

... because the service is essentially going to encapsulate the method for each action of the controller so that it works ...

I still think that you should think about what features that you are currently using in your controllers should be more logically implemented in your domain objects. for example, in your statement example, I think it would be reasonable for the entity to provide an approving method that does everything it needs to do inside the object, and if, as in your example, you need to send emails, delegate this to the service. Services must be reserved for cross-cutting issues . Then, as soon as you finish working with the domain objects, move them back to your repository to save the changes.

A few books that I found useful on these topics:
Project Managed by Eric Evans
Apply domain-driven design and templates by Jimmy Nilsson

0
source share

The only restrictions that NHibernate creates for classes are that all methods / properties must be virtual and the class must have a default constructor (can be internal or protected). Otherwise, it does not [edit] interfere with the structure of the object and can display rather complex models.

0
source share

All Articles