EF4 vs FluentNHibernate/NHibernate

Ok guys, here’s another “why or why not” quandry from me.

With the improvements in Entity Framework version 4.0, it occurs to me that domain driven design can now be done using it, with a small caveat here and there. I’ll cover those caveats after the example.

Example:

I created a single, empty, mvc2 project called “Venue”. In the root folder/namespace I added an EF designer. In it I dropped the two tables: Categories and Forums. I then set the Custom Tool Namespace to “Venue.Entities”.

For the generated Category class, I made the following changes via the properties editor:

  • Made “Id” protected set (identity)
  • Made “Title” protected set (domain signature part)
  • Made “Forums” collection private get and set and renamed it “forums”

For the generated Forumclass, I made the following changes via the properties editor:

  • Made “Id” protected set (identity)
  • Made “CategoryId” private get and set (want this hidden)
  • Made “Title” protected set (domain signature part)
  • Made “Category” protected set

The rest of the fields are public get and set.

I then added the Entities folder to the project and added the following partial classes:


public partial class Category
{
 
// expose the now hidden collection in a read only state
public IEnumerable<Forum> Forums { return forums; }
 
// required for factory method - may use tt to remove it
protected Category() { }
 
// initialize with domain signature parts
public Category(string title) { Title = title; }
 
// wrap add forum - left out error handling for brevity
public void AddForum(Forum forum) { forums.Add(forum); }
 
// wrap remove forum - left out error handling for brevity
public void RemoveForum(Forum forum) { forums.Remove(forum); }
 
}


public partial class Forum
{
 
// required for factory method - may use tt to remove it
protected Forum() { }
 
// initialize with domain signature parts
public Forum(Category category, string title)
{
Category = category;
Title = title;
}
 
// wrap move to - left out error handling for brevity
public void MoveTo(Category category)
{
if (Category != null) Category.RemoveForum(this);
Category = category;
Category.AddForum(this);
}
 
}

I then tested it.

What I found was that EF4 properly maintained the accessability of the class properties I set, making them secure domain objects. Now, obviously I left out sanity checking here, but this is just an example. One cannot set domain signature properties directly. In practice, the current user would be passed in to accessor method like AddForum(currentUser, forumToAdd) and toss exceptions when something isn’t right.

Ok, so here are the caveats…

  1. This really only works if the mapping (edmx) and the entities exist in the same project. This is ok by me though, because I really like the single-project solution anyway.

  2. The compiled classes aren’t pocos. Again, this just very well may excusable as changing the backend isn’t really affected by it. If one were to switch from SqlServer to Oracle, with the same basic footprint, all one needs to do is refresh the edmx from the connected databsae. It will update the existing generated code, but leaves ours intact. So while the conceptual model may change, our entity model will not.

In light of the above test and observations, I see no reason not to use it for smaller single project solutions.

Now, is there any reason not to use it for large solutions?