Living in the Tech Avalanche Generation

A practitioner’s introspective on technology

Archive for September, 2008

LINQ To SQL - Going POCO and more…..!

Ok so I have posted on this a few times and rather than keep it waiting for the code to mature into anything deeper than more than what it is, I have decided to get the example working code up for download now and not keep it hanging around for too long.

A lot of people are expressing a lot of interest in the how to leverage LINQ To SQL using POCO (Plain Old CLR Objects) and this generic Repository approach utilises POCO’s along with Specifications and Fetching strategies (an nHibernate concept). The Repository<T> is designed for use out of the box however it can also be extended. I should make it clear that the code is not yet entirely complete and certainly I wouldn’t yet be releasing to my own team as ratified framework plumbing, nonetheless I am keen to get it posted to finish the discussion I started in previous posts.

The Cut and Thrust

The idea of the generic repository began as an extension of the ideas expressed by Mike Hadlow in his article here which are derived from Ayende’s work here.

public interface IRepository<T>
{
    void Save(T domainObject);
    void SaveAll(IList<T> domainObjects);
    void SaveCompared(T modifiedDomainObject, T originalDomainObject);
    void SaveNew(T domainObject);
    void Delete(T domainObject);
    void Delete(ISpecification<T> spec);
    void Delete(T domainObject, Expression<Func<T, bool>> children);
    void Delete(Expression<Func<T, bool>> predicate);
    IList<T> All();
    IList<T> All(ISpecification<T> spec);
    IList<T> All<TRole>(ISpecification<T> spec);
    IList<T> All(ISpecification<T> spec, IFetchingStrategy strategy);
    T First();
    T First(ISpecification<T> spec);
    T First<TRole>(ISpecification<T> spec);
    T First(ISpecification<T> spec, IFetchingStrategy strategy);
    T Unique(ISpecification<T> spec);
    T Unique<TRole>(ISpecification<T> spec);
    T Unique(ISpecification<T> spec, IFetchingStrategy strategy);
    DataContext UnitOfWork { get; }
}

Were the code really begins to diverge from Mike’s example is where you can see the dependencies that the IRepository has to the ISpecification and IFetchingStrategy, both of which I have posted previously about. ISpecification implements the Specification pattern popularised by Eric Evans in Domain Driven design and our ISpecification provides the ability to test for object equality by matching the specification ; the EvalPredicate is specifically targeted to enabling dynamic expression building and giving us dynamic querying in the process. The design of ISpecification is all but entirely based on Dave Laribee’s Sexy Specifications post, the addition of the EvalPredicate provides the dynamic query functionality.

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

The Fetching Strategy approach enables targeting code for runtime lazy or eager loading strategies and borrows from Udi’s approach with NHibernate and NServiceBus which is to allow for pluggable code that has no compile time coupling to the consumer code, that is, you can literally write Fetching Strategies and drop them in a folder location and if you call the write method in the Repository that accepts a generic paramater as a role or <TRole> [as a hint] then your strategy will be nice enough to load for you.

public interface IFetchingStrategy
{
    DataLoadOptions LoadOptions { get; }
}

/// <summary>
/// Marker Interface
/// </summary>
/// <typeparam name="TRole">
/// Specification of a role for 
/// dyanmic runtime type lookup
/// </typeparam>
public interface IFetchingStrategy<TRole> : IFetchingStrategy{ }

Some DDD’ers very much like to be very explicit with their Repositories in particular in defining the behaviours, such as GetByProductCatalog() for example. The generic approach is taken to reduce the amount of code written in the case where you may need many small repositories with little or no specific behaviours. Having said that you are still free to extend the generic repository and specialise that class.

Here are some samples that exemplify how to use the code to query your database.

public void SimpleRepositoryFetchingStrategyTest()
{
    Specification<Customer> simonsCoSpec =
        new Specification<Customer>(c => c.Country == "Germany");

    DataContext ctx = GetContext();

    Repository<Customer> customerRepository =
        new Repository<Customer>(ctx);

    CustomerLoyaltyDiscountFetchingStrategy strategy =
        new CustomerLoyaltyDiscountFetchingStrategy();

    var custs = customerRepository.All(simonsCoSpec, strategy);

    foreach (var cust in custs)
    {
        cust.LoyaltyDiscount();
        Console.WriteLine("The Name of the Customer from " +
            "Germany is {0}", cust.CompanyName);
        foreach (var order in cust.Orders)
        {
            Console.WriteLine("\tOrder Number {0}", order.OrderID);
            foreach (var orderLine in order.OrderLines)
            {
                Console.WriteLine("\t\tProduct ID {0} Amount {1}",
                       orderLine.ProductID,
                       (orderLine.Quantity * orderLine.UnitPrice));
            }
        }
    }
}

As you can see our CustomerLoyaltyDiscountFetchingStrategy defines a lazy loading approach. It should be noted that Fetching Strategies can also include the use of the AssociateWith method of the DataLoadOptions class which is used to further refine the filtering capabilities of an IFetchingStrategy.

Another upside is that I can write unit tests that do not rely on my database and consequently slow down my testing automation. Ian Cooper demonstrated something similar and this a well known design goal amongst those that practice Domain Driven Design. You can see from the code example below, I am able to supply my repository with in memory objects and mock behaviours without any connection to the database.

[Test(Description="Tests the All method of the " +
                  "Repository for accurate data Retrieval")]
public void SingleExpectationFromAllMethod()
{
    var mockRep = new Mock<IRepository<Customer>>();

    mockRep.Expect(r => r.All()).Returns(() => new List<Customer>()
    {
       new Customer()
           {
               CustomerID = "SIMONS"
           }
    });

    Assert.AreEqual(mockRep.Object.All().First().CustomerID, "SIMONS");
    mockRep.VerifyAll();
}

So that’s it for this topic. Looks for the moment that I will use L2S where appropriate and although the Entity Framework is still pretty clunky and lacking purity in the POCO pursuits, I expect Microsoft to get it right eventually. You can download the entire code here which also includes Kris’ DebuggerWriter for printing SQL statements to the debug window from the LINQ To SQL DataContext and a slightly modified version of the ubiquitous Northwind database.

Share/Save/Bookmark

16 comments

Oslo, SOA BizTalk Express and crossing the chasm (part 3).

With PDC around the corner and the buzz around Oslo beginning to form into some louder noise, it occurs to me that we (developers and architects) should be helping shape the discussion and hopefully make an impression.

If I could hand the Oslo team my single most precious wish it would read like this:

“Can I please have a framework that allows me to build applications that support durable messaging using the publish & subscribe pattern and communicate over a bus!”

That’s the main thing that I crave. In the meantime we can use nServiceBus, SimpleServiceBus, Mass Transit and a few others, including rolling our own with WCF but lets not forget that WCF does not give us this out of the box, in fact far from it.

To date we have heard about how integral Windows Communication Foundation andchasm Workflow Foundation are to Oslo and that XAML activation looms large along with ‘the Repository‘ which might be storage for workflow and service discovery. It would seem that the idea of the ‘Repository’ is about assisting with architecture, but I’m not yet clear about how deep the Repository lives in the API and whether I can leverage it to promote or provide durable pub /sub messaging with a bus architectural pattern. Let’s wait and see what emacs.net, the repository and the so-called new process server bring to the table.

Parts 1 and 2 of this post.

Share/Save/Bookmark

No comments

learning Ruby, IronRuby, the DLR, F# and DSL’s - so much to consider.

ruby I just cant seem to shake Ruby off. Often something comes up in my day to day job that pushes me get serious about Ruby and for as long I have the idea of the Polyglot programmer in the back of my mind, I feel compelled to find out more, even if it’s in microscopic increments. A while back I installed Ruby on my development laptop and played with the interactive console for a while and then predictably got distracted and didn’t follow up for months, until today when I  downloaded NetBeans (Ruby version only) and made a decision, that to understand Domain Languages better I wanted to learn more about a language that would help in that understanding. Ruby is well thought of with respect to being a useful language to ms rubydevelop internal DSL’s and given the other sentiment in this post, I thought it was as good a choice as any. I have been a C# developer since beta of the 1.0 Framework and now that IronRuby and DLR are close at hand, I feel compelled to let my interest in DSL’s, the DLR and learning a dynamic language begin to engulf me to the point that I have been stung into action. So with this in mind I am setting down the path to learn Ruby and hope that this provides a great springboard into taking up IronRuby. Of course the benefit of going deep into another development language and platform I believe will lead to a far richer appreciation of the platform I am currently so deeply invested in.

Last Minute Update:

After re-listening to the HanselMinutes podcast with Robert Pickering on F#, it would appear that F# is a potentially useful language for creating internal DSL’s. I have been thrown a little as I must confess this threw things into debate for a short moment. The argument that kept me down the Ruby path was the relationship that IronRuby has with the DLR and the upside that brings to the learning experience. FsharpYellow Last minute problem solved. Wait hold the press. VbX or Visual Basic 10 is on its way and it too will be a dynamic language. Dilemma. Given that I am almost  equally conversant in VB as C# (I prefer C# by choice), perhaps I should concentrate on F# and let my strong understanding of VB languages to carry me through the transition to VB10 which gives me the DLR leverage? Again I decide to take the Ruby path also because its not a Microsoft Language per se and I think the exposure to Ruby in general will do me good from a platform perspective. I would also like to use Ruby in exploring RESTful Web Services. So I have downloaded NetBeans and installed Ruby 1.8.6 and here I go.

Share/Save/Bookmark

1 comment

« Previous PageNext Page »

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