Geeks With Blogs
Justin a.k.a. The Code Monkey Code Monkey [kohd muhng'-kee] n : 1. Creature known for it's ability to transform caffeine into code. 2. Justin Jones

In my previous post I laid out my current pet project and began showing the framework I set up to isolate CSLA business objects from the data access code. I listed (sans code comments for brevity) the static factory class and interfaces for a data access abstraction. You can find this post here: http://geekswithblogs.net/TheCodeMonkey/archive/2013/03/24/variations-on-a-repository-pattern-part-i.aspx.

Now I need something more concrete to the project at hand. Still without any concrete implementations, I define another set of interfaces explicitly for the project’s data. There’s only a handful of entities in the project, so I can show most of it here.

The project is a relatively simple application that takes video or audio files and makes a podcast feed out of them. That’s all it really does, actually. I’ve simplified the model a little bit for brevity. In the data layer code I define the following XML file:

<?xml version="1.0" encoding="utf-8"?>

<DataDefinition>
    <Entity name="Feed">
        <Property name="Id" type="int" key="true" />
        <Property name="Name" type="string" />
        <Property name="FeedUrl" type="string" />
        <Property name="Image" type="byte[]" />
        <Property name="ImageName" type="string" />
    </Entity>
    <Entity name="FeedItem">
        <Property name="Id" type="int" key="true" />
        <Property name="Title" type="string" />
        <Property name="Description" type="string"/>
        <Property name="Date" type="DateTime?"/>
        <Property name="Path" type="string"/>
        <Property name="FeedId" type="int"/>
        <Property name="EnclosureType" type="string"/>
        <Property name="Enabled" type="bool"/>
        <Property name="Length" type="long"/>
        <Property name="Duration" type="long?"/>
    </Entity>
</DataDefinition>

You’ll notice that there’s a few scalability problems with the way I’ve approached this. That’s fine for my project because it has a user base of 1 (me). It doesn’t need to scale, but if you want to adopt this approach for your own project, you’ll want to address these issues. My scaled down model basically has two entities in it, Feed and FeedItem. The properties match the database schema, which makes some of the implementation issues easier to surmount, but it certainly doesn’t have to match. Keep in mind though, we’re defining data objects, not business objects. To me it makes logical sense for data objects to follow the database schema. However, what we define here is all that the business layer is going to know of the data layer.

The next step could certainly be done by hand, but I decided to use a T4 template to generate the next set of code. Here’s a sample of the template:

    public partial interface I<#= name #>Dto
    {
<#        foreach(var field in entity.Elements("Property"))
        {
            var fieldName = field.Attribute("name").Value;
            var type = field.Attribute("type").Value;
#>        <#= type #> <#= fieldName #> { get; set; }
<#
        }
#>
    }

    public partial class <#= name #>Dto : I<#= name #>Dto
    {
<#        foreach(var field in entity.Elements("Property"))
        {
           var fieldName = field.Attribute("name").Value;
          var type = field.Attribute("type").Value;
#>        public <#= type #> <#= fieldName #> { get; set; }
<#
        }
#>
    }

    public partial interface I<#= name #>Dal : IDal<I<#= name #>Dto,<#= keyType #>>
    {
    }

Without going into too much detail about how T4 templates work, this generates the basic interfaces and DTOs that I need. The generated code looks like so:

public partial interface IFeedDto
    {
        int Id { get; set; }
        string Name { get; set; }
        string FeedUrl { get; set; }
        byte[] Image { get; set; }
        string ImageName { get; set; }
    }

    public partial class FeedDto : IFeedDto
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string FeedUrl { get; set; }
        public byte[] Image { get; set; }
        public string ImageName { get; set; }
    }

    public partial interface IFeedDal : IDal<IFeedDto,int>
    {
    }

And again for the Feed Item. This provides the business object with an interface that it can talk to for all CRUD operations, and interface for the DTO, and a simple concrete implementation that it can use when interacting with the interface. At this point, as far as unit testing is concerned, the data layer is done. I’ll cover some concrete implementations in the next post, but first there’s something missing. To be efficient about, for instance, a fetch operation, you want to filter the FeedItems returned to just the items related to the feed you’re instantiating. Notice that the generated Dal interface is partial. This allows me to add operations to it at the project level, so in another file I can add this:

public partial interface IFeedItemDal
{
   IEnumerable<IFeedItemDto> GetForFeed(int feedId);
}

Any concrete implementation of IFeedItemDal is now required to implement this method as well. In entity framework or linq to sql, you would accomplish this by writing a linq query against the model which in turn generates a sql statement to run against the database. This is still possible, but I’ve abstracted that down to the implementation. It’s certainly possible to do that, but a custom Linq provider was more than I wanted to get into for this project. Basically I’m taking the approach that the interface provides predefined queries and the implementation can accomplish them any way it wants to, including linq statements against EF providers. This is certainly extensible and could include custom types defined at this level for more complex queries.

So now my DataPortal_Fetch method is as simple as this:

private void DataPortal_Fetch(SingleCriteria<int> criteria)
{
    using (BypassPropertyChecks)
    {
        var item=DalFactory.GetManager().GetProvider<IFeedDal>().Retrieve(criteria.Value);
        Mapper.Map(item,this);
        Items=DataPortal.FetchChild<FeedItemCollection>(item.Id);
    }
}

The Mapper.Map line is AutoMapper. If you’re not using AutoMapper, check it out. It’s a life saver on this project. In this case, the DTO closely resembles the actual business object, so I can create a map without any custom mapping code. We’ve probably all written mapping code at some point in our career. I had one of my own that matched up the two objects based on property names and types and only copied the matches. AutoMapper does pretty much the same thing, but it caches the map and doesn’t do it every time which is a huge performance gain.

So obviously FeedItemCollection has the following code

 

private void Child_Fetch(int feedId)
{
    var items=DalFactory.GetManager().GetProvider<IFeedItemDal>().GetForFeed(feedId);
    RaiseListChangedEvents = false;
    AddRange(from item in items
             select DataPortal.FetchChild<FeedItem>(item));
    RaiseListChangedEvents = true;
}

And FeedItem has this:

 

private void Child_Fetch(IFeedItemDto item)
{
    using(BypassPropertyChecks)
    {
        Mapper.Map(item,this);
        BusinessRules.CheckRules();
    }
}

Now I can start my unit tests with this setup code:

 

var repository=new MockRepository();
var dalManager=repository.StrictMock<IDalManager>();
DalFactory.ManagerInstance=dalManager;
var feedDal=repository.StrictMock<IFeedDal>();
dalManager.Expect(n => n.GetProvider<IFeedDal>()).Return(feedDal);
feedDal.Expect(n => n.Retrieve()).Return(new[]
    {
        new FeedDto {Id = 1, FeedUrl = "test.rss", Name = "Test Feed"},
        new FeedDto {Id = 2, FeedUrl = "test2.rss", Name = "Test Feed 2"}
    });
repository.ReplayAll();

As you can see I pass my mocked IDalManager directly into ManagerInstance. What the business object calls will be the mocked object and get back whatever I tell it to return. The business layer is fully unit testable now. In my next post, I’ll cover some implementations of the data layer I’ve thrown together.

Posted on Sunday, March 24, 2013 7:14 PM .Net 4.0 , Visual Studio 2010 , Unit Testing , CSLA , Repository , Data Access | Back to top


Comments on this post: Variations on a Repository Pattern: Part II

# re: Variations on a Repository Pattern: Part II
Requesting Gravatar...
No comments posted yet
Left by mcsa certification on Apr 07, 2013 10:12 PM

# re: Variations on a Repository Pattern: Part II
Requesting Gravatar...
Thanks very much for the specialized and amazing help. I will not hesitate to propose your web site to anyone who needs guidance on this subject. Commodity Online Tips
Left by Tasmini on Jun 25, 2015 12:03 PM

# re: Variations on a Repository Pattern: Part II
Requesting Gravatar...
Fantastic items from you, man. I’ve take into account your stuff previous to and you are simply too excellent. I really like what you’ve obtained here, really like what you are stating and the best way wherein you are saying it. You make it enjoyable and you still take care of to stay it smart. I can’t wait to learn far more from you. That is actually a tremendous site.

This is certainly superior. Please keep posting
http://indiavisitonline.in/package/coimbatore-kullu-manali-honeymoon
Left by Rahjani Roya on Jul 13, 2015 10:13 AM

# re: Variations on a Repository Pattern: Part II
Requesting Gravatar...
It is currently as well as yet again complicated to merely always be giving freely alternatives that many a great many others could have been creating wealth through. We really recognize we have the blog owner to get thankful in order to for that. Khelomcx
Left by Asfaq Ramzani on Aug 20, 2015 7:02 AM

# re: Variations on a Repository Pattern: Part II
Requesting Gravatar...
VERY NICE US LOVE IT

web...Technicalstock
Left by technicalstock on Apr 06, 2016 6:30 AM

# re: Variations on a Repository Pattern: Part II
Requesting Gravatar...
I and a project I just joined are both new to CSLA, I would like to map to and from business objects. This bin directory may contain business DLLs for many applications.
http://mybookistaan.com/2016/05/rpsc-1st-grade-school-lecturer-exam-books
Left by Aswin on May 03, 2016 10:27 AM

Your comment:
 (will show your gravatar)


Copyright © Justin Jones | Powered by: GeeksWithBlogs.net