1

I tried the T4-Template from http://efrepository.codeplex.com, but I'm struggling with the DI (uses StructureMap) Example code. It's just not enough for a DI beginner like me. It doesn't even compile.

I already have done a few sample projects with its Non-DI Template. And it worked out great. I love, that it generates all necessary repositories and that I can easily customize and extend them. But I can't get the DI Examples working. Are there any similar projects (with better docs)?

3
  • Why do you want to use a DI template if you're new to it? Commented Mar 28, 2011 at 11:40
  • To learn it :) Right now, I'm reading/watching some Tutorials. I want to know what I'm doing, before I use it for a real project. Commented Mar 28, 2011 at 11:54
  • Take a look at this article: bit.ly/bF7jL3. It describes a DI and test friendly way of doing repositories. Commented Mar 28, 2011 at 12:02

1 Answer 1

2

I normally use the following setup with EF end Structure map: (brace yourself, bunch o' code coming up).

This is the base interface we'll use to inject our controllers:

public interface ISession : IDisposable
{
    void CommitChanges();
    void Delete<T>(Expression<Func<T, bool>> expression) where T : class, new();
    void Delete<T>(T item) where T : class, new();
    void DeleteAll<T>() where T : class, new();
    T Single<T>(Expression<Func<T, bool>> expression) where T : class, new();
    IQueryable<T> All<T>() where T : class, new();
    void Add<T>(T item) where T : class, new();
    void Add<T>(IEnumerable<T> items) where T : class, new();
    void Update<T>(T item) where T : class, new();
}

And here an ISession implementation with EF in mind:

public class EntityFrameworkSession : ISession 
{
    // MyContext is a class inheriting from EF's DbContext
    readonly DbContext _context;

    public EntityFrameworkSession(DbContext context)
    {
        _context = context;
    }

    public void CommitChanges()
    {
        _context.SaveChanges();
    }

    public void Delete<T>(Expression<Func<T, bool>> expression) 
        where T : class, new()
    {
        var query = All<T>().Where(expression);
        foreach (var item in query)
        {
            Delete(item);
        }
    }

    public void Delete<T>(T item) where T : class, new()
    {
        _context.Set<T>().Remove(item);
    }

    public void DeleteAll<T>() where T : class, new()
    {
        var query = All<T>();
        foreach (var item in query)
        {
            Delete(item);
        }
    }

    public void Dispose()
    {
        _context.Dispose();
    }

    public T Single<T>(Expression<Func<T, bool>> expression) 
        where T : class, new()
    {
        return All<T>().FirstOrDefault(expression);
    }

    public IQueryable<T> All<T>() where T : class, new()
    {
        return _context.Set<T>().AsQueryable();
    }

    public void Add<T>(T item) where T : class, new()
    {
        _context.Set<T>().Add(item);
    }
    public void Add<T>(IEnumerable<T> items) where T : class, new()
    {
        foreach (var item in items)
        {
            Add(item);
        }
    }
    public void Update<T>(T item) where T : class, new()
    {
        //nothing needed here
    }
}

Now this ISession implementation is not very handy to inject because, while being nice and generic, it doesn't have a default constructor, so the way to solve it is by writing a small wrapper that only exposes a parameter-less constructor:

/// <summary>
/// This is the EF site alternative
/// </summary>
public class SiteEFSession : EntityFrameworkSession
{
    public SiteEFSession() : base(new MyContext())
    { }
}

Now we can easily inject it. We set it up in StructureMap as follows:

ObjectFactory.Initialize(x =>
{
    x.For<ISession>().Use<SiteEFSession>();
});

And if you have, for instance, an MVC style controller:

public class HomeController : Controller
{
   private readonly ISession _session;

   // ISession will be injected automatically
   public HomeController(ISession session)
   {
       _session = session;
   }
}

There you go. It's a helluva lot of code but you can pretty much copy/paste it into your solution and you should be good to go.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.