Living in the Tech Avalanche Generation

A practitioner’s introspective on technology
Archive for January 4th, 2010

Helping Entity Framework v4.0 play it’s <ROLE> – Part 1.0

With the Entity Framework version 4.0 just around the corner, I decided it was again time to address how to make the next version work in an explicit role based manner that also satisfies my wish to work with Domain Driven Design. This is the first of four posts that will detail a set of libraries that I currently have on my workbench, their aim is to aid working with the Entity Framework in the manner I shall describe here and throughout this series of posts. I hesitate to call it a Framework quite yet but it may well reach that point by the time of Entity Framework 4.0 RTM. In the meantime, I refer collectively to this set of libraries as NFetchSpec.

Programming to interfaces is not exactly a new idea right. We should all be familiar with the benefits of decoupling from a classes implementation. If this idea is new to you, here are a couple of links, the first is an interview with the venerable Erich Gamma and the other a video interview with WCF Uber Meister Juval Lowy who is also the author of .NET Components.

A couple years back I enjoyed attending Udi Dahan’s SOA and DDD course, during which I learnt about a lesser known benefit of using interfaces, using them to describe roles within the system. It’s just two weeks now until I have the opportunity to once again enjoy Udi’s SOA and DDD 5 day course and whilst I have been sitting on the code from this series of posts for some time now, it felt like now was a good opportunity to talk more about it. Before continuing with this post I strongly suggest you watch this video presentation Udi gave at QCon London in 2008, this will help provide a solid framing of the background that led up to my attempts to massage the Entity Framework into working in this fashion and ultimately making this series of posts.

As I sat in that classroom back in 2008 it was this simple line of code that really captured my attention, it was something of an aha moment.

Listing 1.0

   1: using (ISession s = ORM.OpenSession())
   2: using (ITransaction tx = s.BeginTransaction())
   3: {
   4:     IMakeCustomerPreferred c = s.Get<IMakeCustomerPreferred>(id);
   5:     c.MakePreferred();
   6:     tx.Commit();
   7: }

The line of code to note here is on line 4:, by being explicit and letting the infrastructure code (NHibernate in this case) know what our intention is by specify a role (the IMakeCustomerPreferred interface), we can do some interesting things! We can:

  • Make use IoC and service locate the appropriate Fetching Strategy, that is one designed to best suit the role of making a customer preferred. In this example, we want to eagerly fetch all the orders and order lines to make the appropriate adjustments.
  • Return an appropriately mapped  concrete implementation for the role of IMakeCustomerPreferred. Entity Framework 4.0 code only mapping has made this a possibility.

By being very explicit with the role I can let NFetchSpec do the lifting in finding the most appropriate entities and fetching strategy to load. For performance reasons alone I may have more than one combination. Bear in mind the code in listing 1.0 is part of a service layer and the concrete entity implementing IMakeCustomerPreferred contains a business operation to make a customer preferred – which may involve discounting current orders on hand for example. The equivalent of this block of code for the Entity Framework could indeed abstract away all the following code:

static void Main(string[] args)
{
    var builder = new ContextBuilder<ObjectContext>();

    builder.Configurations.Add(new CustomerMapping());
    builder.Configurations.Add(new OrderMapping());

    builder.RegisterSet<Customer>(“Customers”);
    builder.RegisterSet<Order>(“Orders”);

    var cnxString = “Server=BOOMER\\BOOM09;Database=CodeOnly;”+
        “Trusted_Connection=True;MultipleActiveResultSets=true”;
    var connection = new SqlConnection(cnxString);

    var context = builder.Create(connection);

    var custs = context.CreateObjectSet<Customer>();

    context.Connection.Close();

    context.ContextOptions.LazyLoadingEnabled = true;

    foreach (var cust in custs)
    {
        Console.WriteLine(cust.FirstName +
            ” has {0} orders”, cust.Orders.Count());
    }
    Console.ReadLine();
}

 

Some of the accompanying Mapping Code

public class CustomerMapping : EntityConfiguration<Customer>
{
    public CustomerMapping()
    {
        Property(c => c.CustomerId).IsIdentity();
        Property(c => c.FirstName).HasMaxLength(50).IsRequired();
        Property(c => c.LastName).HasMaxLength(50).IsRequired();
        Relationship(c => c.Orders).IsOptional();
        Relationship(c => c.Orders).FromProperty(o => o.Customer);
    }
}

public class OrderMapping : EntityConfiguration<Order>
{
    public OrderMapping()
    {
        Property(o => o.OrderId).IsIdentity();
        Relationship(o => o.Customer).IsRequired();
        Relationship(o => o.Customer).IsRequired().FromProperty(c => c.Orders);
    }
}

Before we delve into NFetchSpec deeply in the following posts, let’s take a quick look at some typical consumer code:

image

Notice also that there is no orthogonal technology bleed in this code, my ORM technology knows nothing of my business entities and my business entities know nothing of my ORM technology. The CustomerBuyingStatusRepository class is a specialised IRepository and through IoC we get the right ObjectContext, the correct mapping, the type of Customer entity that we make preferred and with the correct eager loading to bring across the orders and order lines in one go.

If you want to gain a better understanding of working in this style then I really do urge you to go and watch this video and then return here to continue and follow this series of posts.

If your not sure about Fetching strategies you can get up to speed by reading these links. They will also be useful in preparing the ground for this series of post which relates only to Entity Framework 4.0:

This series of posts (probably 4 in total) will cover the same aspects that were covered in the 11 part series on Repositories, Fetching Strategies and Specifications, however we will look at how the story around most of those elements in NFetchSpec have been improved by virtue of some of the new excellent features in Entity Framework 4.0, such as POCO Entity support and Code Only Mapping which will not feature entirely in 4.0 but sometime (hopefully) shortly after. In part 2.0 we will begin to deep dive into NFetchSpec and I will make the code available for download.

Share/Save/Bookmark

8 comments

Creative Commons Attribution-ShareAlike 2.5 Australia
Creative Commons Attribution-ShareAlike 2.5 Australia