Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use NHibernate without altering a DDD model that is part of a framework

I dig a lot of things about the DDD approach (Ubiquitous language, Aggregates, Repositories, etc.) and I think that, contrary to what I read a lot, entities should have behavior rather then being agnostic. All examples I see tend to present entities with virtual automatic properties and an empty constructor (protected or worst, public) and that's it. I consider this kind of objects more like DTOs then entities.

I'm in the process of creating a framework with its specific API and I don't want to be tied to an ORM. So I built the domain first (without thinking of persistence) and now I would like to use NHibernate as persistence tool so I added a new project to my current solution to help ensure that my model isn't altered to support NHibernate. This project should be an implementation of the abstract repositories that live inside my domain. And now the difficulties arise.

Since it is my first time with NHibernate (I'm also trying Fluent Nhibernate but it seems even more restricting) I would like to know :

  1. Is it possible to use NHibernate without altering a DDD model that is part of a framework
  2. The things (constraints) that are necessary for NHibernate to work as expected and efficiently (virtual properties, empty constructors, etc.) I think this list would be helpful to a lot of people who are starting to learn NHibernate.

Please keep in mind that I'm building a framework so the Open/Closed Principle is very important for me.

P.S.: Sorry if my english is not good, I'm from Montreal and I speak french.

Edit 1: Here is one problem I have with NHibernate now - How to map Type with Nhibernate (and Fluent NHibernate)

like image 828
W3Max Avatar asked Oct 03 '09 17:10

W3Max


1 Answers

  • For NHibernate:
    • All mapped classes require a default (no-arguments) constructor. The default constructor does not have to be public (it can be private so that it is not a part of the API), but it must exist. This is because NHibernate must be able to create an instance of the mapped class without passing any arguments. (There are workarounds, but don't do that.)
    • All mapped properties for which lazy-loading will be required must be marked virtual. This includes all reference properties and all collection properties. This is because NHibernate must be able to generate a proxy class deriving the mapped class and overriding the mapped property.
    • All mapped collection properties should use an interface as the property type. For example, use IList<T> rather than List<T>. This is because the collections types in the .NET Framework tend to be sealed, and NHibernate must be able to replace a default instance of the collection type with its own instance of the collection type, and NHibernate has its own internal implementations of the collection types.
    • For NHibernate, prefer Iesi.Collections.Generic.ISet<T> to System.Collections.Generic.IList<T>, unless you are sure that what you want is actually a list rather than a set. This requires being conversant in the theoretical definitions of list and set and in what your domain model requires. Use a list when you know that the elements must be in some specific order.

Also note that it's typically not easy to swap object-relational mapping frameworks, and in many cases it is impossible, when you have anything beyond a trivial domain model.

like image 100
yfeldblum Avatar answered Sep 29 '22 14:09

yfeldblum