Living in the Tech Avalanche Generation

A practitioner’s introspective on technology

Archive for the 'Design Patterns' Category

Entity Framework 4.0 and Fetching Strategies

I have spent a fair amount of time already trying to improve my experience with the Entity Framework with versions 1.0, 2.0 and 3.0. Well that’s a bit of joke really because there was and never will be versions 2.0 or 3.0 for the Entity Framework with the decision to take the next version straight to Version 4.0 to align with the .Net Framework Version. Nonetheless I have previously spent quite a bit of time working at being more explicit with how to fetch data with the Entity Framework.

Fetching Strategies are a key concept when considering tuning your data access code in Event Driven Architectures. By using ‘roles’ to explicitly fetch data either eagerly, lazily or some combination thereof, we can build fetching strategies to load accordingly when a role has been specified. The role can be reasoned as a business event of sorts. Udi has written extensively on this and developed a method for using fetching strategies with NHibernate and if you haven’t yet checked out what he’s had to say to date on the subject I suggest you take a look.

With Entity Framework 4.0 I wanted to refine my approach taken with EF 1.0 previously. Fetching Strategies are a key component in the framework (which I call NFetchSpec4Ef) and helps me work in a manner that fit’s with my use of Domain Driven Design.

Demonstrate your intentions

Before we get to the strategies themselves we need some way to state our intent with regards to fetching data and so this leads us to Fetching Intentions.

public class EagerFetchingIntention
{
    private static EagerFetchingIntention _factory_intent;
    private readonly string _fetchAssociate;

    public string FetchAssociate
    {
        get { return _fetchAssociate; }
    }

    internal EagerFetchingIntention(string fetch)
    {
        _fetchAssociate = fetch;
    }

    private EagerFetchingIntention() { }

    public static EagerFetchingIntention
            CreateInstance<TRootEntity, TFetchEntity>
            (Expression<Func<TRootEntity, TFetchEntity>> fetch)
    {
        if(fetch == null)
            return new EagerFetchingIntention(string.empty);

        int dot = fetch.Body.ToString().IndexOf(“.”) + 1;
        string includes = fetch.Body.ToString().Remove(0, dot);

        _factory_intent =
            new EagerFetchingIntention(includes);

        return _factory_intent;
    }
}

We can chain intentions together with a fluent interface provided by an .And()extension method.

public static class EagerFetchingIntentionExtensions
{
    public static EagerFetchingIntention And(
                this EagerFetchingIntention original,
                EagerFetchingIntention addTo)
    {
        EagerFetchingIntention compound_intention;

        compound_intention =
            new EagerFetchingIntention(
                original.FetchAssociate +
                “.” + addTo.FetchAssociate);

        return compound_intention;
    }
}

Fetching Strategies Refactored

Like all parts of NFetchSpec4Ef, Fetching Strategies needed to be rethought as part of addressing the 4.0 changes to the Entity Framework and in particular it’s new support for POCO entities and (somewhat) implicit lazy loading. So what do Fetching Strategies look like now? Fetching Intentions remained (as seen above) but generally speaking the API changed somewhat.

public interface IFetchingStrategy
{
    IList<EagerFetchingIntention> Intentions { get; }
    IEnumerable<string> Includes { get; }
    void AddIntentions(EagerFetchingIntention[] intentions);
    bool ShouldLazyLoad { get; }
    bool HasInstructions { get; }
}

public interface IFetchingStrategy<TRole> : IFetchingStrategy { }

These two interfaces form the basis of Fetching Strategies in NFetchSpec4Ef. In the next version of NFetchSpec4Ef, the implementation no longer required implementing these interfaces directly when creating a new strategy, rather we inherit from a super class that has already done this for us. You might also notice that the aspects to this interface for non-public consumption have been hidden through explicit implementation.

public class FetchingStrategy : IFetchingStrategy
{
    private readonly IList<EagerFetchingIntention> _intentions;
    private readonly bool _includeDeferedLoading = default(bool); 

    public FetchingStrategy(bool useDeferedLoading)
    {
        _includeDeferedLoading = useDeferedLoading;
        _intentions = new List<EagerFetchingIntention>();
    }

    private FetchingStrategy() { }

    public void AddIntentions(EagerFetchingIntention[] intentions)
    {
        if ((intentions == null) || (intentions.Count() < 1))
            return;
        intentions.ToList().ForEach(i => _intentions.Add(i));
    }

    public IEnumerable<string> Includes
    {
        get
        {
            if(((IFetchingStrategy)this).HasInstructions == false)
                return new List<string>().AsEnumerable();

            IEnumerable<String> includes =
                (from intents in _intentions
                select intents.FetchAssociate).AsEnumerable();
            return includes;
        }
    }

    IList<EagerFetchingIntention> IFetchingStrategy.Intentions
    {
        get { return _intentions; }
    }

    bool IFetchingStrategy.ShouldLazyLoad
    {
        get { return _includeDeferedLoading; }
    }

    bool IFetchingStrategy.HasInstructions
    {
        get { return _intentions.Count > 0 || _includeDeferedLoading; }
    }
}

Our goal includes notifying our infrastructure of our fetching intent by being explicit through the use of roles which have been defined as Interfaces. The infrastructure is able now to employ IoC / DI to locate the most appropriate Fetching Strategy from a container. This frees us to swap out fetching details for specific business events, after all, in some situations such as “IMakeCustomerPreferred” (see below), I might want to eager fetch all my customers orders and order lines in one go. Here’s the base class implementation of IFetchingStrategy<T> for role based fetching strategies,  followed by a custom Fetching Strategy:

public abstract class FetchingStrategyForRoles<TRole> :
        FetchingStrategy, IFetchingStrategy<TRole>
{
    public FetchingStrategyForRoles(bool useDeferedLoading) :
        base(useDeferedLoading) { SetupIntentions(); }

    public abstract void SetupIntentions();
}
class CustomerPreferedFetchingStratey :
        FetchingStrategyForRoles<IMakeCustomerPrefered>
{
    public CustomerPreferedFetchingStratey()
        : base(false) { }

    public override void SetupIntentions()
    {
        var orders_intention =
            EagerFetchingIntention
            .CreateInstance<Customer, IList<Order>>(c => c.Orders);
        var orderlines_intention =
            EagerFetchingIntention
            .CreateInstance<Order, IList<OrderLine>>(o => o.OrderLines);

        var iFetch = this as IFetchingStrategy;

        iFetch.AddIntentions(new EagerFetchingIntention[]
            {
                orders_intention,
                orders_intention.And(orderlines_intention)
            });
    }
}
This custom strategy will produce two “includes” strings for ObjectQuery<T> to work with, “Orders” and “Orders.OrderLines”. From the consumers point of view we would be writing code that looked something like this:
var repo =
    new EntitiesRepository<NorthwindEntities, Customer>
        (new NorthwindEntities());

repo.Get<IMakeCustomerPreferred>();

We leave the container (IoC) to deal with locating the right fetching strategy based on the role of IMakeCustomerPrefered. The dependency injection happens inside of the Repository.

The next part of NFetchSpec4Ef to discuss will be how Specifications fit in and what they offer to Repositories.

Share/Save/Bookmark

4 comments

GOF Series: Episode #5 : [The Prototype Pattern] - In IronRuby

Firstly let me mention that whilst this series started out as demonstrating the Gang of Fours patterns in C# I have since decided to change direction a little bit and have the rest of the series presented in IronRuby. Why? My Reasons are twofold, firstly there are probably more than enough examples of the patterns in C# that another one will certainly not be missed and second completing the series in IronRuby will serve as great learning tool on the way to better knowing the language. I have previously posted on the Builder Pattern implemented in IronRuby and for that example I used Sapphire in Steel to develop the code and I am really hoping that we get a great code editor for IronRuby when it makes it’s official debut.

What purpose does this pattern serve?

Implementing the prototype pattern facilitates creating a prototypical object and subsequently being able to produce copies of that prototype.

Example Code:

First lets start with our Vehicle manager which will hold the prototyped vehicles that we wish to take copies of.

class VehicleManager
    def initialize
        @cars = {}
    end
    def add key, prototype
        @cars[key] = prototype
    end
    def remove key
        @cars.delete key
    end
    def get_vehicle_by_key key
        @cars[key].deep_copy
    end
end

Next we create a module that we will use as a mixin to extend a ‘vehicles’ behaviour to include cloning.

module Cloneable
    attr_accessor :id
    attr_accessor :horse_power
    def deep_copy
        Marshal.load(Marshal.dump(self))
    end
end
Now some some Cloneable vehicles that our Vehicle manager can work with.
class Car
    include Cloneable
    def initialize horse_power, id
        @id = id
        @horse_power = horse_power
    end
end

class MotorCycle
    include Cloneable
    def initialize horse_power, id
        @id = id
        @horse_power = horse_power
    end
end

All that’s left is to look at how to create some prototype’s using these classes.

$counter = 1

#new up a VehicleManager to store vehicles
#that we are interested in cloning
vmanager = VehicleManager.new

#add a car and motor cycle to the manager
vmanager.add :eighty, Car.new(80, $counter)
$counter += 1
vmanager.add :ninety , MotorCycle.new(90, $counter)

#retrieve clones of the car and motor cycle
vehicle_car = vmanager.get_vehicle_by_key :eighty
vehicle_bike = vmanager.get_vehicle_by_key :ninety

#print the results
puts “The horse power for the car is “ +
     “#{vehicle_car.horse_power} and the ID is :#{vehicle_car.id}”
puts “The horse power for the motor cycle is “ +
     “#{vehicle_bike.horse_power} and the ID is :#{vehicle_bike.id}”
console_ir_prototype_pattern
Yet again the brevity of IronRuby (Ruby) comes to the fore and true to the languages nature, interesting things can be done with less code when you compare to our statically typed friends. I am definately gaining a real appreciation for “composition over inheritance” and as the static languages are now crossing the paradigm divides with features clearly borrowed from both the functional and dynamic worlds, should we be expecting to get the ability to compose our objects in C# or VB.NET sometime in the future?

Share/Save/Bookmark

No comments

LINQ To XML and the Specification Pattern - [In a static world]

I have documented quite extensively on how to use the Specification Pattern and in particular how that can work with a variety of LINQ flavours. The pattern has proven useful in matching objects based on a computation that seeks to test equality and when turned slightly on it’s head a little, it can provide dynamic querying capability to the current Microsoft group of ORM products, namely LINQ To SQL and the Entity Framework. You can check out most of the series on this topic from here. In more recent times I looked at how to use the same pattern with IronRuby which whilst very satisfying for the author, it currently lacks the ability to produce expressions that either ORM products are capable of utilising.

So, for the moment I want to go back again to the Specification pattern and explore it’s use specifically in the world of C# and it’s statically typed sibling languages. The Specification that I currently use is based primarily around our ability to push around Expression<Func<T>> and Func<T> as delegates that can be used as arguments to the extension methods in a given LINQ implementation. Therefore, LINQ to XML should be no exception. Given that the class at the centre of all this ( Specification<T> ) matches objects that satisfy a boolean condition that is asserted using the generic T argument, we are able to specify a function to pass to any extension method implemented by the LINQ To XML provider, that takes a generic as it’s input parameter and returns a boolean. A quick reminder of the Specification classes interface:

public interface ISpecification<T>
{
    Expression<Func<T, bool>> EvalPredicate { get; }
    Func<T, bool> EvalFunc { get; }
    bool Matches(T entity);
}

Here is a simple example of filtering a query over XML data by supplying a predicate in the form of a specification.

public void employees_from_uk()
{
    var all_employees_on_file =
        XDocument.Load(@"..\..\XML\Employees.xml").Descendants();

    Specification<XElement> aus_emp_spec =
        new Specification<XElement>
            (x => x.Attribute("Country").Value == "Australia");

    var aus_employees = from e in all_employees_on_file.Descendants()
                        .Where(aus_emp_spec.EvalFunc)
                        select e;

    aus_employees.ToList().ForEach(x =>
        { Console.WriteLine(x.ToString()); });
}

And now a more complex specification that uses the AND operator to create a combined set of conditions to be satisfied in a .Where extension method.

public void employees_from_uk_that_are_ceo()
{
    var all_employees_on_file =
        XDocument.Load(@"..\..\XML\Employees.xml").Descendants();

    var aus_emp_spec =
        new Specification<XElement>
            (x => x.Attribute("Country").Value == "UK");

    var ceo_emp_spec =
        new Specification<XElement>
            (x => x.Attribute("Title").Value == "CEO");

    var compound_spec = aus_emp_spec & ceo_emp_spec;

    var aus_employees = from e in all_employees_on_file.Descendants()
                        .Where(compound_spec.EvalFunc)
                        select e;

    aus_employees.ToList().ForEach(x =>
        { Console.WriteLine(x.ToString()); });
}

More than just a ‘Where’ predicate?

Your probably noticing that we are always applying our specifications to the “where” method. As I mentioned, a Specification in it’s current incarnation can only be applied to extension methods that take a function that accepts a generic argument as an input parameter and returns a boolean, therefore there are some other methods that can be specified. Here is example of using the .SkipWhile() extension method.

public void skip_while_employees_from_usa_then_return_the_rest_regardless()
{
    var all_employees_on_file =
        XDocument.Load(@"..\..\XML\Employees.xml").Descendants();

    var usa_empoyee_spec =
        new Specification<XElement>
            (x => x.Attribute("Country").Value == "USA");

    var usa_emps = from e in all_employees_on_file.Descendants()
                       .SkipWhile(usa_empoyee_spec.EvalFunc)
                       select e;

    usa_emps.ToList().ForEach(x =>
        { Console.WriteLine("Skipping from the USA : " +
            x.ToString()); });
}

The final example combines data from two XML sources, each one requiring it’s own specification, where the LINQ query will bring the disparate data together.

public void customer_joined_with_customer_representative()
{
    var cust_rep_spec =
        new Specification<XElement>(x => x.Name == "CustomerRep");
    var emp_id_spec =
        new Specification<XAttribute>(x => x.Name == "EmployeeID");

    var all_employees_on_file =
        XDocument.Load(@"..\..\XML\Employees.xml").Descendants().Attributes();

    var all_customers_on_file =
        XDocument.Load(@"..\..\XML\Customers.xml").Root.Descendants().Elements();

    var customer_with_rep =
        from c in all_customers_on_file.Where(cust_rep_spec.EvalFunc)
        from e in all_employees_on_file.Where(emp_id_spec.EvalFunc)
        where c.Value == e.Value
        select new
        {
            c = c.Parent.Element("FirstName").Value + " " +
                c.Parent.Element("LastName").Value,
            e = e.Value
        };

    customer_with_rep.ToList().ForEach(x =>
    {
        Console.WriteLine(
            string.Format("Customer : {0} is represented by Rep Number {1}",
            x.c, x.e));
    });
}
 
For ease of reading this code without the necessity of downloading the code, I have included the XML directly in the post here.
 

Employee.xml File

 
<?xml version="1.0" encoding="utf-8" ?>
<Employees>
  <Employee EmployeeID="1" FirstName="Nancy"
            LastName="Davolio" Title="Sales Representative"
            HireDate="1992-05-01T00:00:00" Country="USA"
            Extension="5467" />
  <Employee EmployeeID="2" FirstName="Andrew"
            LastName="Fuller" Title="Vice President, Sales"
            HireDate="1992-08-14T00:00:00" Country="AUSTRALIA"
            Extension="3457" />
  <Employee EmployeeID="3" FirstName="Janet"
            LastName="Leverling" Title="Sales Representative"
            HireDate="1992-04-01T00:00:00" Country="USA"
            Extension="3355" />
  <Employee EmployeeID="4" FirstName="Margaret"
            LastName="Peacock" Title="Sales Representative"
            HireDate="1993-05-03T00:00:00" Country="AUSTRALIA"
            Extension="5176" />
  <Employee EmployeeID="5" FirstName="Steven" LastName="Buchanan"
            Title="Sales Manager" HireDate="1993-10-17T00:00:00"
            Country="UK" Extension="3453" />
  <Employee EmployeeID="6" FirstName="Michael"
            LastName="Suyama" Title="Sales Representative"
            HireDate="1993-10-17T00:00:00" Country="UK"
            Extension="428" />
  <Employee EmployeeID="7" FirstName="Robert" LastName="King"
            Title="CEO" HireDate="1994-01-02T00:00:00"
            Country="UK" Extension="465" />
  <Employee EmployeeID="8" FirstName="Laura" LastName="Callahan"
            Title="Inside Sales Coordinator"
            HireDate="1994-03-05T00:00:00" Country="USA"
            Extension="2344" />
  <Employee EmployeeID="9" FirstName="Anne" LastName="Dodsworth"
            Title="Sales Representative" HireDate="1994-11-15T00:00:00"
            Country="UK" Extension="452" />
</Employees>

 

Customers.xml File

<?xml version="1.0" encoding="utf-8" ?>
<Customers>
  <Customer>
    <FirstName>Simon</FirstName>
    <LastName>Segal</LastName>
    <JoinDate>19-10-2008</JoinDate>
    <Country>Australia</Country>
    <Email>simon.segal@techavalanche.com</Email>
    <MobilePhone>0405987367</MobilePhone>
    <CustomerRep>2</CustomerRep>
  </Customer>
  <Customer>
    <FirstName>Bob</FirstName>
    <LastName>Jones</LastName>
    <JoinDate>23-10-2008</JoinDate>
    <Country>Germany</Country>
    <Email>bob.j@bundes.com</Email>
    <MobilePhone>8983478347</MobilePhone>
    <CustomerRep>1</CustomerRep>
  </Customer>
  <Customer>
    <FirstName>Clair</FirstName>
    <LastName>Humgola</LastName>
    <JoinDate>10-10-2008</JoinDate>
    <Country>Australia</Country>
    <Email>chumg@telstra.com.au</Email>
    <MobilePhone>0458193487</MobilePhone>
    <CustomerRep>4</CustomerRep>
  </Customer>
  <Customer>
    <FirstName>Milton</FirstName>
    <LastName>Nomik</LastName>
    <JoinDate>20-12-2008</JoinDate>
    <Country>Australia</Country>
    <Email>milt.n@techavalanche.com</Email>
    <MobilePhone>09072625717</MobilePhone>
    <CustomerRep>6</CustomerRep>
  </Customer>
</Customers>

On a final note: I am going to have a go shortly at putting together some variations of the Specification<T> class to allow for a more complete use with LINQ in General, remembering that the initial requirement was based around testing objects for equality and then creating a more manageable and malleable system of creating dynamic queries in LINQ To SQL and the Entity Framework. The “new” Specification class will need to support more than the just Func<T, bool> and should prove to be in interesting exercise.

Full code download for this post can be found here.

Share/Save/Bookmark

No comments

Next Page »

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