;

Creating a persistence ignorant POCO application using various ORM solutions

Posted : Sunday, 14 November 2010 14:15:59

Some time ago I bought a copy of Julie Lermans excellent book Programming Entity Framework, I really liked the way that it has been implemented but the lack of support for POCOs was a bit of a let down. The restriction that all entities must inherit from EntityObject was enough of a reason for me not to use it. I often like to fiddle about with inheritance and move features around and the requirement that EntityObject be top of the inheritance chain was too prohibitive for me. With the release of Visual Studio 2010 and .Net 4 there has been a reasonable amount of publicity surrounding all the new features available but the one I was most keen to try was POCO support in EF4. Persistence ignorance is, for good reason, a goal that many developers strive for when building software systems and I decided to write this series of posts to detail my experiences of adding persistence to a simple (and persistence ignorant) application using 3 of the more popular ORM tools available for .Net namely EntityFramework, LinqToSql and NHibernate

In this, the first in series of posts, I will outline the simple application that will be used during the subsequent posts. The application itself is not intended as a production ready system and could without doubt be improved upon however for the purposes of this assay it is completely suitable. A fictional movie memorabilia company want to set up a new website where registered members are able to bid for famous items and props as featured in various movies over the years, the application itself is to be called "LightsCameraAuction".

So let’s get down to the nitty gritty, the model. After a brief period of jotting, scribbling, reflecting, musing, starting-over etc. I identified four business objects (entities) that are required in order to model this simplified application, each of these is listed below with a brief explanation.

  • ItemAn Item is any object of movie memorabilia for which an Auction is held.
  • BidderA Bidder is a customer or registered member of the site who is able to participate in an Auction.
  • BidA Bid is an offer made against an item by a Bidder. A Bid has a single reference to a Bidder and a single reference to an Item.
  • AuctionAn Auction is a process that runs for a fixed period of time. Each Auction has one Item. During the Auction, Bidders can submit one or more Bids for the Item with higher value Bids taking precedence. When the Auction ends, the Bid with the highest value becomes the winning Bid.

As well as the entities listed above there are a few other parts of the domain model for LightsCameraAuction: for each of the business objects I created a corresponding repository strongly typed to the relevant entity, abstracted into interfaces, to manage persistence of that entity. I also created a class called AuctionService which contains all the business logic for the domain model and acts as a facade by providing the public interface for the model. The final object in the domain model is an abstract class called LcaModule from which each implementation will create a subclass to acts as means by which different implementations can be selected easily (more on this later).

    6     public abstract class LcaModule : NinjectModule

    7     {

    8         public const string MetadataBindingParamName = "DataProvider";

    9 

   10         public abstract string MetadataBindingParamValue { get; }

   11     }

I created a new class library project called LcaModel and added all of the entities described above. I am using Ninject to manage dependency injection for this blog series.
NB Typically during the design phase of such a project I would use the CommonServiceLocator project but for the purposes of this essentially throw away app I feel that the extra layer of abstraction provided is unnecessary.

Most of the classes in this project are fairly simple but a couple of them warrant a more explanation Auction Service: AuctionService as stated, contains the business logic required to administer the Auction process. The constructor of this class takes an instance of each repository interface and stores each in a class level private member. The Auction service has various methods used to add and retrieve entities from the model. There are also two other methods of note. The first IsBidAvailable is listed below:

   44         public bool IsBidAvailable(Bidder bidder, Item item, double maxPrice, out double currentPrice)

   45         {

   46             var topBid = _bidRepository.GetTopBidForItem(item);

   47 

   48             currentPrice = topBid == null ? 0 : topBid.BidPrice;

   49 

   50             if (topBid == null || (topBid.Bidder.BidderId != bidder.BidderId && topBid.BidPrice < maxPrice))

   51     

  • (This will not appear on the site)