Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Billy McCafferty



DDD with ADO.NET Entity Framework?

[Updated Feb. 13, 2008:  A couple of commenters noted that since the generated model is made up of partial classes, then additional partial classes could be developed to encapsulate domain-specific extensions to the model.  I hadn't noticed this originally and appreciate it being pointed out to me.  With that said, though, this leads me to my next question (since I usually eschew partial-classes):  is this a good design practice?  My gut tells me that it should be avoided, but perhaps I'm being too closed minded after working with NHibernate since version 0.84.]

For the past year or so, there seems to have been an overwhelming community outcry for getting back to a simpler separation of presentation and logic within ASP.NET applications.  The success of Castle MonoRail and the introduction of Microsoft's MVC.NET reflect such direction.  So while I applaud Microsoft's bold move towards simpler ASP.NET development, I'm left wanting after taking a closer look at the upcoming ADO.NET Entity Framework.

After spending a few hours playing with ADO.NET Entity Framework Beta 3, using a tutorial for porting ScottGu's MVC.NET code as a starting point, I was left with the feeling that Microsoft has enabled us with terrific ORM generation capabilities; but with the caveat that it can only be used on the most simplistic of CRUD applications.  It's quick to setup, it's great with legacy databases, and it makes data communications all but invisible.  So what's the rub?  The problem, and this is the kicker for me, is that it greatly impairs one's ability to take a domain-driven design approach to product delivery.

In DDD, the business logic lives with the domain objects themselves.  As infoq.com eloquently states, DDD "is based on making the domain itself the main focus of the project, and maintaining a software model that reflects a deep understanding of the domain."  This idea, that the model reflects the domain itself, is a pivotal one in taking a DDD approach to development.  With the ADO.NET Entity Framework, the model is nothing more than a DTO layer with ActiveRecord capabilities; it generates a model layer with get/put statements and persistence methods but without providing the ability to augment the model with domain-specific logic within the model itself.

 For example, suppose you have an Employee object generated by the ADO.NET Entity Framework.  In less than two seconds, you have a nice Employee object with built-in database communication capabilities.  Now suppose you want to add a GiveRaiseOf(Money amount) method to the Employee object which executes a bit of business logic to calculate new estimated taxes or whatever.  You cannot add this method directly to the model within an ADO.NET Entity Framework generated model object; alternatively, you could inherit from the generated Employee object and augment it accordingly (ack!) or you create a logic layer which essentially provides a decorated layer of functionality on top of the auto-generated model.  (There are other options such as extension methods, AOP, but nothing IMO that provides clean and simple DDD.)  Essentially, when using objects generated by the ADO.NET Entity Framework, you're forced to separate domain logic from the model itself; thus, impairing the ability to take a clear DDD path towards development.

I am writing this post for two reasons:  1) to possibly be told that I'm dead wrong and to be explained what the simple way is for augmenting ADO.NET Entity Framework generated model objects with domain-specific logic within the model itself, and 2) to save you some research time if you prefer a DDD approach and it turns out I'm right. ;)

In short, and at the risk of being laconic, I feel that the ADO.NET Entity Framework does for data communications what the ASP.NET page life cycle did for the presentation layer.  In trying to introduce simplification and increased productivity, it's actually going to result in higher complexity and decreased maintainability in the long run.  I appreciate what Microsoft is trying to do, and absolutely love some of their other ideas, but, for now, I'm going to pass on the ADO.NET Entity Framework.

Billy McCafferty



Comments

Dave^2 said:

The Entity Framework generates partial classes, so rather than using inheritance you can add a "GiveRaiseOf(Money amount)" method to Employee by providing the rest of the partial implementation.

# February 13, 2008 8:19 PM

pete w said:

This needed to be said. The "drag-and-drop domain object generator" was literally designed by the same guy who gave us the "drag-and-drop strongly-typed datasets".

I'm very weary when I see this: back in 2004, they recommended deriving business logic classes from computer-generated datasets. If history repeats itself, you will see a thousand basic examples of northwind only to discover that it scales out pitifully with any nontrivial domain complexity...

# February 13, 2008 8:38 PM

Billy McCafferty said:

It would certainly be interesting to see how maintainable and clear a large scale project would be if partial classes were used to augment the model with domain logic.  After using NHibernate for the last few years, I find that I spend so little time writing the get/set properties and HBMs, that's it's hard for me to think about giving up direct control of the model.  Perhaps I'm being too close minded...but I'd love to see more discussion over this.  Specifically, what drawbacks might be incurred from using partial classes to augment the models besides having each model object being split physically in half.  How might this affect data exposed via web services or passed to a web layer?  There are other concerns it brings up and further discussion is certainly welcome.

# February 13, 2008 8:51 PM

Steve Gentile said:

I'm not sure Billy, with generated code the partials offer a way to extend those classes without getting them overwritten.  I think it's just a fact of dealing with generated code.

A benefit would be that it's clear what is generated vs. what is specific domain logic calls.

The negative would be switching back and forth between different partials.  Obviously a best practice for me would be to logically separate the domain logic partials vs. the generated logic partials.

Actually, if you really think about it - the generated is acting like the DAL, where as the business layer partials contain true business logic.

With this, the DAL can change, you can use the UI to make changes to the generated code without necessarily breaking those business rules.

Perfect? no.  A reality of dealing with generators... probably.

# February 13, 2008 10:01 PM

Sean Chambers said:

Not to mention the obvious:

True DDD focuses on your domain to the point that it should be completely agnostic as to how and where it persists itself to some backend storage. This statement attacks the activerecord pattern as a whole but at least with NHibernate I have a choice as to which approach to take.

Thanks for the heads up Bill

# February 13, 2008 10:14 PM

pete w said:

I'm just saying that if persistence is supposed to be an afterthought, it kinda grosses me out, on an aesthetic level that my objects take a back seat to microsoft's latest persistence technology.

What if I wanted my business objects to all inherit from a common abstract ancestor? That seems like a reasonable thing to do, but I cant clearly see how to do that if I'm forced to derive from generated code.

# February 13, 2008 10:36 PM

El Guapo said:

Two words: Partial Classes

# February 13, 2008 11:33 PM

Steve Bohlen said:

I too am going to pass on the EntityFramework, largely because I've been an NHibernate adopter for a number of years now and don't see anything in EF (planned for 1.0)  to make me abandon my existing tooling.

That being said, I think its worth keeping an eye on this thing if only b/c its going to be a 1.0 release that the EF team acknowledges is really trying to align w/ Pareto's Principle: do 20% of the work that will cover 80% of the cases.  While its true that EF 1.0 lacks any number of things that are going to be needed for it to become a real O/RM replacement technology for just about any O/RM technology with a several-year headstart (Nhib or others out there), its likely that over time this thing will begin to 'catch up' in features and become a viable alternative to those of us who build solutions 'at the edges' where we alwasy seem to hit the 20% not covered by the 80-20 rule :)

# February 14, 2008 6:11 AM

» Daily Bits - February 14, 2008 Alvin Ashcraft’s Daily Geek Bits: Daily links, development, gadgets and raising rugrats. said:

Pingback from  » Daily Bits - February 14, 2008 Alvin Ashcraft’s Daily Geek Bits: Daily links, development, gadgets and raising rugrats.

# February 14, 2008 9:01 AM

Billy McCafferty said:

Very true Steve!

# February 14, 2008 10:37 AM

Neal Blomfield said:

I think EF is more like the first of a series of small bridges to a true ORM. Microsoft has promoted a database first / the database is the domain model approach for a long time and while they are definately making moves to shift away from that paradigm or support parallel approaches, it will take time.

It also pays to remember that there are still a lot of .net "developers" out there who still think WebForms are the one true way and believe datasets are all you need for persistence.   Small steps is the best way to wean people off this addiction to knowing the relational model while building the domain layer.

# February 14, 2008 2:06 PM

Ruurd Boeke said:

I have introduced a first stab at easing your problem here: www.codeplex.com/efcontrib

Introduction post here: www.sitechno.com/.../IntroducingEntityFrameworkContribEasyIPocoImplementationV01.aspx

It's not persistence ignorance, but will let you get away with just creating classes and one attribute. It will then do a postcompilation to create all the goo that EF needs.

# February 18, 2008 7:56 AM

Steve Gentile said:

I should ask, do they support command line like sqlmetal that will put the mappings in a file like nhibernate does?

This was a common complaint with linq to sql until I found it you have the same option as you do in nhibernate.

nhibernate uses attributes or external files.  

Seems to me if you want to manually, by hand create files, then you can do that as well.

Guess we need to examine if there are command line switches with EF.

By the way, does nhibernate now support mapping one class to multiple tables?

With Ayende's latest post on Linq to NHibernate, I think NHibernate will always continue to be the extensible alternative that has a proven track record

# February 21, 2008 6:16 PM

Guillaume said:

First of all, I should say that I really appreciate this blog.

The first and major point for me is that, for the time being, EF is only targeting SQLServer. I will not consider using it (or even sample it) unless it's open to other databases.

Moreover, I Saw a presentation from Microsoft about EF during the tech days in Paris and I'm not convinced. It sounded very much like a marketing advertisement. Something useless as soon as you step out of the demo.

It's the bigger difference between open source and private worlds. Open source focus on what is usable. Companies like Microsoft focus on what they could sell (and that's perfectly normal).

I see EF as a tool I might have an eye on, but not like something I could use in my developper's daily life. At least for the moment.

# March 6, 2008 5:50 PM

Ruurd Boeke said:

Guillaume, EF is not only targeting SQL server. It has a provider model and there are lots of DB's working on implementations. Microsoft will only supply a SQL server implementation itself, and the community will do the rest. That is no different than other or-mappers. So I do not see your point.

Second, I'm working with EF a lot for EFContrib. I can say that EF is definitely up for the task. It might be less flexible in some ways than nHibernate, but it is more flexible in others.

I wish you would write comments based on actual experience, instead of a feeling you got from a presentation.

# March 14, 2008 4:51 PM

Guillaume said:

I'm sorry if you fill unconfortable with my post, but my purpose (as was M. McCafferty's if I understand well) was precisely to get feedback from people really knowing this tool, because I precisely don't. I wish I should have time to sample and make myself a precise idea, but I have not.

As an architect/developper my concern is my job's constraints against the usage and availability of technologies, not the fact that Microsoft company did or did not implement it (of course they will not provide Sybase or MYSQL implementation !).

As you know the product, I wish you would write your feelings and knowledge about this tools more precisely than "flexible", instead of judging me...

# March 14, 2008 6:13 PM

Sharas said:

Forget about generated classes at all. It is nothing more than a fancy way of describing how to henerate SQL from generated classes relationships. It cannot be exposed outside your data access layer IMO. If there is any value in EF for average enterprise application, it is in its abillity of mapping you BL object (not generated off course) relationships to your DB table relationships. Effectively acting as a Data Mapper.
# July 11, 2008 4:53 PM

luke said:

The problem with the premise in this article is that you would place behaviour into your model.  IMO a true MVC pattern (maybe implementing Dependancy Injection) is a far better approach.  In other words let the model be the model nothing more or less, and place your behaviour somewhere else.  Maybe utilise a provider pattern??

This would allow you to use entity framework as you would any other modeling system (i.e. nhibernate).

# October 1, 2008 7:40 PM

Billy McCafferty said:

Hi Luke,

The scenario that you describe is very model-driven in nature and very appropriate for Entity Framework.  When the behavior is within the model, it is more of a domain-driven design.

# October 5, 2008 12:41 PM

Tim said:

I think the argument against partial classes is a moot point. If you work in .Net technologies then you HAVE leveraged the encapsulation provided by partial classing. For example, those win form, web form and even XAML UI technologies all implement partial classes to instantiate and set properties for all the UI controls (remember -- InitializeComponent()) , while you write the "real" UI logic in a different partial class. So how is this any different? Because we are at a different layer?

# December 15, 2008 1:12 PM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add
Check out Devlicio.us!

Our Sponsors

Proudly Partnered With