While playing with Linq and trying to get it to work with Oracle (Linq to Oracle *sigh*), I struggled with the fact that Linq appears to tightly couple business objects with data/persistence. 

I found myself pondering this fact and trying different approaches to separate the ObjectContext from EntityContext(s).  In Linq, the ObjectContext is the object that you provide with a connection string and has the knowledge to send/receive data to/from your database.  The EntityContext(s) are the classes that define your domain model, including relationships.  I looked at various ways to attempt this separation and none of them panned out.  My ultimate goal was to have the classes in separate libraries, but, the classes are generated and are in the same file. 

I even contacted the great guys responsible for Linq (check out Dinesh's Cyberstation), and they provided very useful input.  However, I finally decided to take a step back and ask myself why was it so hard to force what I wanted.  Was Linq a fit for my design?  After careful consideration, I answer "No, but..."  What it really comes down to is years of experience with mediocre designs.  What I wanted to do is extend the EntityObjects to add my business logic.  Perhaps there is better way.

Think about the Single Responsibility Principle (cohesion).  Am I trying to make my "business objects" do too much?  I wanted to put validation logic and other actions in a partial class to extend the EntityObject.  If I were to do that, there would be a lot going on in that class ("There should never be more than one reason for a class to change.").  Validation logic can be handled by separate validator classes (or a framework like Spring.Net).  And, "other actions" sounds a bit fishy.

I have become a fan of MVC/MVP.  (I promised a review of Microsoft's MVC Toolkit (.Net 3.5 - MVC), but I haven't gotten there yet.)  I think a lot of people don't understand that the real benefit behind MVC is not in simplifying the UI code.  That is just a nice side effect.  The real benefit is moving business "logic" or "flow" to one place, the Controller.  You don't even have to have a UI to take advantage of MVC.   In fact, I think that this is where "other actions" belong.  Let the Controller be responsible for coordinating all of the objects involved in these "actions".  Of course, don't let MVC become your hammer and try to see everything as a nail.

In summary, Linq has forced me to rethink my design.  In the end, I think that is a good thing.  I have had to remind my self of design principles that are easily forgotten.  So, I will let Linq do what it is good at, and I will build other classes that are each good something else.

Tags: ,
posted on Thursday, February 28, 2008 1:57 AM
Filed Under [ .Net Design Tools Design Principles ]


# re: Linq Design
posted by Jimmy Junatas
on 2/29/2008 7:36 AM

This would be a natural question for Active Record implementations as the generated Entity classes essentially takes the place of the Table Module classes. Where do you now attach the validation and transformation rules?

My first inclination would to subclass the generated class like:

public class MyCustomer : Customer
// rules
// transformation

On the other hand, it is bit easier to see where Linq fits in a Domain Model system. While it will be very tempting though to fold the Linq work into the Repository (to minimize the amount of mapping work), anything Linq-To-SQL need to stay in the persistence layer. The Entity classes or the results of Linq queries will take the DTO role between the domain and persistence layers.

Post A Comment