Saturday, May 30, 2009

Entity Framework POCO Repository using Visual Studio 2010 .Net 4.0 Beta 1

Note: This article applies to beta software and comes with no warranty or support, use at your own discretion. You must have Visual Studio.Net 2010 Beta 1 installed on your machine to make use of the code.

Update 25/06/2009: This article should be read first, however, see next article here which uses asp.net mvc and db4o object database with updated code now hosted at codeplex at http://kandaalpha.codeplex.com/
http://blog.keithpatton.com/2009/06/25/db4o+POCO+Repository+Using+Visual+Studio+2010+Net+40+Beta+1+And+ASPNet+MVC+10.aspx

Download KandaAlpha v1 Code Now

Introduction

Before i delve into the details, it’s worth providing a bit of context on this post. For a number of years i’ve been a big fan of ORMs (object relational mappers) for helping get in memory software objects into and out of databases.

I’ve gradually moved away from a data-centric view of the world, towards a transition to domain driven design methodologies in architecting more complex enterprise applications.

My ORM of choice has up until around a year ago been NHibernate. I used it for a few years and grew to love it’s power and flexibility. But it always felt and still is a bit of a black art to make sing. And the tool and Linq support has never really matured to a level where i thought it was really going to take off.

Then along came the Entity Framework from Microsoft. I compared it and NHibernate during the .net 3.5 SP1 beta period and concluded that whilst it was architecturally inferior in many ways to NH, the availability of a designer, integrateion with Visual studio and .net combined with the sheer muscle of Microsoft dollars convinced me to give it a shot.

It was a success and saved me a lot of time, although i did have some pain taking EF across tiers usign web services, although the pain would likely have been there but in a different way with NHibernate. You can see some relatively popular previous posts are related to EF, with the Vote of Confidence in EF (in riposted to Alt.Net’s Vote of No Confidence) and also the code for the Polymorphic Repository for Entity Framework 1.0 (or what is now being called 3.5!).

And now we have Entity Framework 4.0. It is abundantly clear that the EF team have listened, learned and produced an ORM to be proud of. Whilst there will likely be gripes in various camps, we now have full POCO (plain old CLR object) support, lazy (deferred) loading support, AND model first design which allows us to create domain models and have the database generated from that. Very cool indeed.

So that’s the introduction. What i’m attempting to do at this early stage is to clearly demonstrate a DDD inspired layered architecture which combines a Repository pattern, injection of control (IoC) using the Microsoft Unity Application Block (swap out for your favourite IoC) and an Entity Framework 4.0 repository implementation.

The Architecture

Presented below are 4 logical layers, Presentation, Application, Domain and Infrastructure (a good overview of the DDD Layers). The rectangles are logical components within each layer (represented in code as .net assemblies). The full head arrows are runtime dependencies between the various libraries which sit within a particular layer. The dotted lines represent runtime dependency injection via our inversion of control tool of choice.

IMG

The Presentation Layer contains a web application (MVC wasn’t available in the Vs.net 2010 Beta 1 so I just used a ‘normal’ web application).

Then we have an Application Layer which has a class library of interfaces to define the behaviour of the implementing services which are in another class library. The services are injected using IoC as implementations of the application interfaces (we’ll see how that’s done later using Unity). The application layer co-ordinates requests from the presentation layer and makes use of the Repository in doing so.

The Domain Layer contains our Domain Model and Repository. The domain model has no dependencies to any other component or layer. The Repository consists of interfaces which define the behavior of the Repository implemented which is injected using IoC. The Repository represents a ‘store’ view of domain objects, underpinned by some form of persistence framework in the Infrastructure layer.

Lastly we have an Infrastructure Layer. In our example architecture this is the Entity Framework repository implementation and persistence framework. The class library has classes which implement the Domain’s Repository interfaces as well as having dependencies on the core EF classes and libraries.

Overall, this is a relaxed layered architecture in the sense that we have decent separate of concerns between the layers but we do allow cross layer dependencies. For example the domain model types are used within the web application (rather than have an extra layer of interfaces or data transfer objects).

The key point in this architecture is that the means by which domain objects are persisted is separated from the domain objects themselves. In addition, we have a  Repository is defined within the domain layer, whilst its implementation is injected using IoC. The domain layer as a whole therefore has no awareness of or build dependency on the underlying persistence framework.

 

 

 

The Solution

SolutionStructure

Here is the architecture represented as a Visual Studio.Net solution. You can see that I’m using Solution Folders to represent the various layers and then using class libraries for each layer component with the exception of the presentation layer which is represented by an asp.net web application. KandaAlpha is just a sandbox prefix I’m using.

For completeness please do note the Base Libraries folder which simply contains the IoC facade to the Microsoft Unity Application Block and also a references project housing the Unity application block dlls.

 

 

 

 

 

 

The Client Code

This first bit of code is the client api view at the asp.net web application level.

// get the customer service using IoC (Unity)
var custService = IoCWorker.Resolve<ICustomerService>();

// get the customer repository from the customer service
var custRepository = custService.GetRepository();

// get all customers and bind to grid
dgCustomers.DataSource = custRepository.GetAll();
dgCustomers.DataBind();

// use a specific method on customer repository
var kp = custRepository.GetBestCustomer();

// display customer's full name
litCustomerName.Text = kp.FullName;

// demonstrate lazy/deferred loading (not for production!)
litFirstOrderTotal.Text += kp.Orders.First().OrderTotal.ToString();

The basic idea here is that we request a service from the IoC container, and the service then provides the ability to fulfill a particular orchestration or unit of work.

You can see from the code that the ICustomerService implementation allows us to get a repository implementation to get all customers, to get the best customer, and also to get the first order total of the best customer. Note how lazy/deferred loading is working for the last call.

And hey presto, a very exciting screen is produced. (Note that the database is stored within App_Data in the web project. This would obviously be a remote SQL server in a production environment, i just wanted to provide the source fully contained)

FinalPage

Wiring up Unity IoC

Here’s how the inversion of control is wired up. See the containers element were we set up a single container and then set up the container to wire particular class implementations as singletons for each particular interface we are interested in providing a service implementation for. Take a look at the small KandaAlpha.Ioc.IocWorker static facade class which combined with configuration initialises the container and provides the hook into resolving service implementations for interfaces via the Resolve<T>() method.

<unity>
    <typeAliases>
      <!-- Lifetime manager types -->
      <typeAlias alias="singleton"
           type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,
               Microsoft.Practices.Unity" />
      <typeAlias alias="perThread"
           type="Microsoft.Practices.Unity.PerThreadLifetimeManager,
               Microsoft.Practices.Unity" />
      <typeAlias alias="external"
           type="Microsoft.Practices.Unity.ExternallyControlledLifetimeManager,
               Microsoft.Practices.Unity" />
      <!-- User-defined type aliases -->
      <typeAlias alias="ICustomerService"
      type="KandaAlpha.Application.Interfaces.ICustomerService, KandaAlpha.Application.Interfaces" />
      <typeAlias alias="CustomerService"
           type="KandaAlpha.Application.Services.CustomerService, KandaAlpha.Application.Services" />
      <typeAlias alias="IGenericRepository"
           type="KandaAlpha.Domain.Repository.IGenericRepository`1, KandaAlpha.Domain.Repository" />
      <typeAlias alias="GenericRepository"
           type="KandaAlpha.Infrastructure.Repository.EF.GenericRepository`1, KandaAlpha.Infrastructure.Repository.EF" />
      <typeAlias alias="ICustomerRepository"
           type="KandaAlpha.Domain.Repository.ICustomerRepository, KandaAlpha.Domain.Repository" />
      <typeAlias alias="CustomerRepository"
           type="KandaAlpha.Infrastructure.Repository.EF.CustomerRepository, KandaAlpha.Infrastructure.Repository.EF" />

    </typeAliases>
    <containers>
      <container name="containerOne">
        <types>
          <type type="ICustomerService" mapTo="CustomerService">
            <lifetime type="singleton" />
          </type>
          <type type="IGenericRepository" mapTo="GenericRepository">
            <lifetime type="singleton" />
          </type>
          <type type="ICustomerRepository" mapTo="CustomerRepository">
            <lifetime type="singleton" />
          </type>
        </types>
      </container>
    </containers>
  </unity>

Domain Model

Nice, POCO classes, nothing relating to persistence or Entity Framework in here, just as it should be. All is right in the world;)

using System;
using System.Collections.Generic;

namespace KandaAlpha.Domain.Model.Entities
{
    public class Customer : EntityBase
    {
        public int CustomerID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string FullName
        {
            get
            {
                return FirstName + " " + LastName;
            }
        }
        public virtual List<Order> Orders {get; set;}
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace KandaAlpha.Domain.Model.Entities
{
    public class Order : EntityBase
    {
        public int OrderID { get; set; }
        public Customer Customer { get; set; }
        public decimal OrderTotal { get; set; }
    }
}

Domain Repository

So, IoC gives us an implementing class for ICustomerService which has a method GetRepository() which returns an ICustomerRepository implementation.

Leaving aside some of the wiring within the Application.Services component, let’s take a look a the ICustomerRepository interface defined within the Domain.Repository component

using System;
using KandaAlpha.Domain.Model.Entities;

namespace KandaAlpha.Domain.Repository
{
    public interface ICustomerRepository : IGenericRepository<Customer>
    {
        Customer GetBestCustomer();
    }
}

So, we have a single custom method on this repository, but most of the action is within the IGenericRepository<T>) class which defines our core repository behaviour as follows.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using KandaAlpha.Domain.Model.Entities;

namespace KandaAlpha.Domain.Repository
{
    public interface IGenericRepository<T> : IRepositoryBase where T : EntityBase
    {

        /// <summary>
        /// Return strongly typed IQueryable
        /// </summary>
        IQueryable<T> GetQuery();

        /// <summary>
        /// Load entity from the repository (always query store)
        /// </summary>
        /// <typeparam name="T">the entity type to load</typeparam>
        /// <param name="where">where condition</param>
        /// <returns>the loaded entity</returns>
        T Load(Expression<Func<T, bool>> whereCondition);

        /// <summary>
        /// Provides explicit loading of object properties
        /// </summary>
        void LoadProperty(T entity, Expression<Func<T, object>> selector);

        /// <summary>
        /// Returns all entities for a given type
        /// </summary>
        /// <returns>All entities</returns>
        List<T> GetAll();

        /// <summary>
        /// Add entity to the repository
        /// </summary>
        /// <param name="entity">the entity to add</param>
        /// <returns>The added entity</returns>
        void Add(T entity);

        /// <summary>
        /// Save all changes from repository to store
        /// </summary>
        /// <returns>Total number of objects affected</returns>
        int SaveChanges();

        /// <summary>
        /// Mark entity to be deleted within the repository
        /// </summary>
        /// <param name="entity">The entity to delete</param>
        void Delete(T entity);

    }
}

As you can see from the Unity IoC configuration ICustomerRepository is wired up to CustomerRepository within the Infrastructure.Repository.EF component. You can see hopefully how you could modify this to be NHibernate, ADO.Net or an in memory provider for quick testing if needs be by just changing the IoC configuration.

EF Repository Implementation

The core job of the EF Repository implementation is to then implement the ICustomerRepository and IGenericRepository<T> interfaces.

2009-05-30_2303[1]

The CustomerRepository and GenericRepository classes also make use of a static ObjectContextManager class. This implements a lifecycle management pattern across the EF’s object context which is one per http request (if HttpContext.Current is available) or one per thread for non web applications.

The EF’s edmx model class goes in this class library too. I followed the very simple instructions around how to enable POCO support for Entity Framework which largely entailed switching off code generation in the properties window of the edmx, nice!

Note the hand crafted KandaAlphaContext class which allows me to specify exactly what happens when the context gets created, including lazy loading options as follows:

 

public KandaAlphaContext() : base("name=KandaAlphaEntities", "KandaAlphaEntities")
{
    _customers = CreateObjectSet<Customer>();
    _orders = CreateObjectSet<Order>();
    base.ContextOptions.DeferredLoadingEnabled = true; // lazy loading
}

There is lastly an HttpRequestModule class which simply kills the object context at the end of each http request. For non web applications you would explicitly kill the context at the end of each unit of work. (although i haven’t yet got a facade method for that on the repository as yet).

Summary

I’m a big fan of the new Entity Framework. I think that the EF team are going to get this release spot on and we’ll see Entity Framework really establish itself as the ORM of choice for Microsoft developers. It will be interesting to see what the Alt.Net community make of EF v2 (sorry v4!), but from what i can see they’ve hit all the right buttons this time around. We’ll likely be talking about specific features, or sql optimisation as opposed to core architectural gripes this time around i feel.

As a big NHibernate fan too, I’m disappointed that Microsoft can’t co-opt more proven open source software like with JQuery as it’s a real boon to the .net community to have these projects flourish.

Saturday, May 30, 2009 11:31:16 PM (New Zealand Standard Time, UTC+12:00)  #    Disclaimer  |  Comments [12]  |  Trackback
 Saturday, May 23, 2009

asp.net development on a mac

Well, sort off…

The idea is that you have designer types who hate windows and will get ill with prolonged usage. So as to make sure you have an adequate supply and flow of decent mark up coming your way as a developer it’s in your best interests to ensure designer type is safely ensconced within the comfort zone of single button mice and strange looking speakers.

We use team foundation server, otherwise known as TFS, which helps us to manage the source control of all our development efforts. In addition, it helps us manage work items (tasks and bugs) during software projects.

If you are on a Mac and are working with TFS, you need this:
http://www.teamprise.com/products/explorer/

OK, so you can work with source control and work items, big deal, how do you actually run an asp.net website?. Well, thanks to the wonders of virtualisation you simply run a windows vm with an iis website as required and give it an appropriate host header such as macdebug.projectname.mycompany.net. Ensure FTP server is running on your windows vm with an appropriate login so that you can copy files to this website via ftp from your Mac.

Now, back on your good old macintosh, you create a TFS workspace and get latest on your lovely TFS solution to have the files locally on your mac. You use your favourite text or html editor and work on the files, checking them out and in as required, and doing all your work items, great. Obviously visual studio is the tool of choice for .net development but if all your tasks are around working with content assets, mark up and styling related files then you don’t really need all that overhead.

All you need to do is ensure that for each change you make that you have an action to FTP the file that has been changed across to the IIS website via FTP automatically. This ensures that you have the IIS website running off your latest changes.

Last thing you need to do is create a hosts file entry on your mac to point macdebug.projectname.mycompany.net to the IP address of your windows vm. Then you can fire up safari and browse to http:macdebug.projectname.mycompany.net to see your asp.net website!

I’ll post up some visuals and details on the tools we’re using on the mac when I have them.

Saturday, May 23, 2009 6:41:29 PM (New Zealand Standard Time, UTC+12:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, May 22, 2009

Expression for Arts Sake

Friday, May 22, 2009 10:14:59 PM (New Zealand Standard Time, UTC+12:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Saturday, May 16, 2009

Where is my mind Wolfram?

image

Saturday, May 16, 2009 2:46:27 PM (New Zealand Standard Time, UTC+12:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, May 13, 2009

Lia Rose Patton – 28 Weeks

Lia Rose - 28 Weeks

Wednesday, May 13, 2009 10:32:55 PM (New Zealand Standard Time, UTC+12:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Saturday, May 02, 2009

Tommy Pics from April

Here’s a collection of pics from my phone i forgot to upload before.

Payback time! Tommy can now bring the bins in, one less job for me on Friday afternoon;)

Tommy Strong Man

Tommy got an easel for his birthday, he loves drawing on this, wiping it clean and saying “good as new”

26042009734260420097332604200973226042009731

The famouse Earthrace 100% biodiesel thingy that went around the world was in Paunaui last month

 

110420097291104200972811042009726

 

Tommy and Freya on their Wiggles date

290320097252903200972429032009723290320097212803200971628032009715

Tommy at Rainbow’s end…

150320097131503200971115032009710

150320097091503200970814032009707

Tommy at Hugh’s birthday party

1403200970614032009705140320097041403200970308032009701Tommy Birthday Pirate01032009694

Saturday, May 02, 2009 2:59:02 PM (New Zealand Standard Time, UTC+12:00)  #    Disclaimer  |  Comments [0]  |  Trackback

IE8 Customisation – Moving Stop and Refresh Icons next to Back and Forward

I just started playing with Windows 7 RC1 and thought, i know i’ll try IE8 again, see if they’ve fixed up the main usability thing that was always annoying me which was the way the Stop and Refresh icons were on the other side of the browser from the back and forward icons.

After struggling with the Tools menu i came across this blog post.

http://blogs.msdn.com/ie/archive/2009/04/20/customization-in-ie8.aspx

Right-click IE8 command bar then select Customise > 'Show Stop and Refresh Icons before Address Bar’

If you remove all the toolbars you get a really clean interface with all the navigation buttons next to one another.

 

image

Saturday, May 02, 2009 2:29:09 PM (New Zealand Standard Time, UTC+12:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Saturday, April 18, 2009

IIS7 Extensionless Urls and Kentico CMS 4.0

Disclaimer: This post contains unsupported guideline for configuring your Kentico CMS 4.x to utilise extensionless urls with IIS 7.0. Use with care!

Base System Requirements: IIS 7.0 with .net 3.5 SP1 on a Windows Vista dev machine or Windows 2008 server to utilise extensionless urls.

Firstly, install the marvellous IIS 7.0 URL Rewrite Module
Get it here: http://www.iis.net/downloads/default.aspx?tabid=34&g=6&i=1692
Learn about it here: http://learn.iis.net/page.aspx/460/using-url-rewrite-module/

Now, make sure Kentico is configured not to interefere with things…

Kentico automatically applies a filter to the form tags. You need to disable this here:

  • Site Manager > Settings > Output Filters >
  • Ensure the ‘Excluded output form filter URLs’ value is set to a single forward slash.. /
  • Site Manager > Settings > Urls>
  • Ensure the Friendly Url Extensions value is blank

There is currently no way of ensuring that automatically generated urls from Kentico contain a trailing slash. The user must set the Document UrlPath for each page in Page > Properties > Urls to include the trailing slash. However the trailing slash is enforced via in IIS 7 rewriting rule. It is hoped that a future version of Kentico will allow for this to avoid the extra 301 redirect.

Now apply the following website configuration….

Place the following code in the Page_Load of your master page.
            // ensure we fix up the form action if required
            if (!String.IsNullOrEmpty(Request.ServerVariables["HTTP_X_ORIGINAL_URL"]))
            {
                form1.Action = Request.ServerVariables["HTTP_X_ORIGINAL_URL"];
            }

This ensures that Asp.Net postback and ajax work correctly with the IIS7 URL Rewrite Module

Now all you need to do now is apply whatever special rewriting rule syou like within the web.config, utilising the IIS Rewrite Module’s capabilities as you need them. (Note that you don’t need to do anything within IIS, you can manage everything within the web.config and simply deploy it out to target servers without worrying about any additional configuration).

For example, the EnforceTrailingSlash rule below will ensure that a trailing slash is added to all urls without extensions, performing a 301 redirect in the process. This is so to avoid multiple urls (ones with and without slashes) returning the same content which isn’t ideal from an SEO perspective.

The TrailingSlashToAspx rule below will ensure that a trailing slash is rewritten internally to .aspx, so that the kentico rewriting engine can take over. Note that the Kentico CMS folders are ignored (ones starting with CMS..)

<system.webServer>
        <rewrite>
            <rules>
                <rule name=”EnforceTrailingSlash”>
                    <match url=”^(.*)$” ignoreCase=”false” />
                    <conditions>
                        <add input=”{REQUEST_FILENAME}” matchType=”IsFile” negate=”true” />
                        <add input=”{REQUEST_URI}” negate=”true” pattern=”(.*)\.([a-zA-Z]+)(\?.*)?$” />
                        <add input=”{REQUEST_URI}” negate=”true” pattern=”(.*)/$” />                       
                    </conditions>
                    <action type=”Redirect” url=”{R:1}/” redirectType=”Permanent” />
                </rule>

                <rule name=”TrailingSlashToAspx”>
                    <match url=”^(.*)/$” />
                    <conditions>
                        <add input=”{REQUEST_FILENAME}” matchType=”IsFile” negate=”true” />
                        <add input=”{REQUEST_URI}” negate=”true” pattern=”/cms(.*)$” />
                        <add input=”{REQUEST_URI}” negate=”true” pattern=”^(.*)/\.aspx[#\w=\|\&amp;%-]*$” />
                    </conditions>
                    <action type=”Rewrite” url=”{R:1}.aspx” />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>

And so there you have it, a relatively painless way to get yourself all SEOd with IIS 7.0 and Kentico CMS 4.0.

Saturday, April 18, 2009 10:06:50 PM (New Zealand Standard Time, UTC+12:00)  #    Disclaimer  |  Comments [1]  |  Trackback

Tommy’s 3rd Birthday

2009-04-18 2009-04-18 001 0062009-04-18 2009-04-18 001 0042009-04-18 2009-04-18 001 0022009-04-18 2009-04-18 001 001DSC03805DSC03804DSC03803DSC03802DSC03801DSC03800DSC03799DSC03798DSC03797DSC03796DSC03795DSC03794DSC03794DSC03793DSC03792DSC03791DSC03790DSC03789DSC03788DSC03787DSC03786DSC03785DSC03784DSC03783

Saturday, April 18, 2009 9:20:57 PM (New Zealand Standard Time, UTC+12:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, April 10, 2009

Yellow Maps now live

We’ve just launched another brand spanking new website for Yellow in Yellow Maps. It gives you the ability to do general map and direction searches a la Google but also do specific yellow business listing searches. You can layer on points of interest and see these pop up on your directions from one place to another.

The site was built using Kentico CMS 4, .Net 3.5 SP1, JQuery and the Yellow and Google APIs. Thanks to Calvin, Darren, Campbell and late night pizza from Hell we made it!

Friday, April 10, 2009 1:25:21 PM (New Zealand Standard Time, UTC+12:00)  #    Disclaimer  |  Comments [4]  |  Trackback