Creating an Abstraction Layer with POCO entity generator

by rcats on December 20, 2010

When creating a decoupled (web)application using interfaces is a given. Where I always run into trouble is when using tools like LinqToSQL or Entity framework, my code get’s coupled to the context. It’s not always a problem, but sometimes it just doesn’t feel right.

I want to design an IContext Interface, have my Model implement this interface, and create a Repository service that will accept an I context interface as a property or constructor parameter. Much nicer.

To do this, we are going to use the ADO.Net C# POCO entity generator. This basically add a couple of (2) T4 templates that can create POCO (plain old class object, without knowledge of things that aren’t it’s concern) classes and a context based on your data context. Which is awesome.

First step, use the Visual Studio extension manager to add the generator templates. I’m assuming you already have an Entity Model (.edmx) in your solution, which will automatically be added as a source for the code generation templates template.

ExtensionManagerCapture

Now in the properties for you Entity Model, change the value for “Code Generation Strategy” to “None”. We are going to use the T4 templates to generate them after all.

Next, let’s create an interface, for example like so:

public interface IContext
{
    IObjectSet tblUsers { get; }
    IObjectSet messageLog { get; }
    IObjectSet tblUserStates { get; }
    int SaveChanges();
}

And let’s also create a repository

public interface IRepository
{
    User GetUserByName(string name);
}
 
public class Repository : IRepository
{
    IContext context;
    public Repository(IContext lecontext)
    {
        context = lecontext;
    }
 
    public User GetUserByName(string name)
    {
        return context.tblUsers.SingleOrDefault(r => r.alias == name);
    }
}

By adding the extension, you added two files that look like [NAME].tt and [NAME].context.tt to your project. Underneath [NAME].tt you’ll find your model entities are created. Please note that they are not inheriting from EntityObject. BTW, you don’t have to use the templates and can create the classes by hand, but the templates make life easier. This works because the 4.0 version of the context is smart enough to figure it out!

We’ll leave [Name].tt as is and open the [NAME].context.tt file. This looks a bit funky if you are new to T4 templates, but all we have to do is make sure that our interface, IContext, is added upon context generation. In one of the first lines, you’ll find something like

<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#>

And change this to inherit from our interface.

<#=Accessibility.ForType(container)#>; partial class <#=code.Escape(container)#>
: ObjectContext, IContext

As you can see in the IContext Interface, we are returning IObjectSet instead of ObjectSet, so we have to change this in the template as well. There’s two occurrences in the template, so change them.

Please note that we have now changed the template that creates our code. If you look at the [Name].context.cs file, you’ll see the changes reflected. There’s no point in making the changes in the .cs file, cause, well, it’s generated. Also note we changes the generated methods to use IObjectSet, but the method names get generated from the model and your IContext interface must match the name.

So, with this setup, we have a nice separation of concerns. We can use the Repository in our classes. On that subject, I was watching another brilliantly funny Scott Hanselman presentation where he mentioned that if you start writing hardwiring code like this,

    IRepository repo = new Repository();

you’re not doing it right (quit your job and start selling taco’s or something along those lines).

In my next post I’ll write about ninjecting our way out of this. I’ll add a video tutorial doing all of this as well when I find the time to do it.

Cheers, Rinze

Tell Everyone:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Reddit

One comment

Alternatively, you can download my project on Codeplex. I have a working example that you can copy.
https://entityinterfacegenerator.codeplex.com/

by Believe2014 on April 25, 2014 at 16:07. Reply #

Leave your comment

Not published.

If you have one.