3

I'm developing an ASP.NET MVC 5 Web API application with C#, .NET Framework 4.5.1, Entity Framework 6.1.1 and the latest version of Ninject (I have also installed Ninject.MVC5).

I'm learning how to implement dependency injection, and I think I have learned it, but I have a question. These are my interfaces and classes.

Unit of work interface:

public interface IUnitOfWork
{
    void Commit();
}

Custom DbContext implementation (I use IUnitOfWork interface to allow DI):

public class EFDbContext : DbContext, IUnitOfWork
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        [ ... ]
    }

    public void Commit()
    {
        this.SaveChanges();
    }
}

And this is how allow Dependency Injection with Ninject and Ninject.Web.Common.

I have a class, NinjectConfigurator, that adds bindings:

public class NinjectConfigurator
{
    public void Configure(IKernel container)
    {
        // Add all bindings/dependencies
        AddBindings(container);

        // Use the container and our NinjectDependencyResolver as
        // application's resolver
        var resolver = new NinjectDependencyResolver(container);
        GlobalConfiguration.Configuration.DependencyResolver = resolver;
    }

    private void AddBindings(IKernel container)
    {
        ConfigureLog4net(container);

        container.Bind<IUnitOfWork>().To<EFDbContext>().InRequestScope();
        container.Bind<IGenericRepository<User>>().To<GenericRepository<User>>();
    }

    private void ConfigureLog4net(IKernel container)
    {
        log4net.Config.XmlConfigurator.Configure();
        var loggerForWebSite = LogManager.GetLogger("MattSocialNetworkWebApi");
        container.Bind<ILog>().ToConstant(loggerForWebSite);
    }
}

And finally, I have this on NinjectWebCommon:

/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
    var containerConfigurator = new NinjectConfigurator();
    containerConfigurator.Configure(kernel);
}

I use .InRequestScope() because I want a EFDbContext instance per request.

My question is: When do I have to do EFDbContext.SaveChanges()? If I'm using one instance per request I think I have to save the changes at the end of the request, isn't it?

Where do I have to put EFDbContext.Commit()?

VansFannel
  • 45,055
  • 107
  • 359
  • 626
  • The answer to your question is buried deep inside [this Stackoverflow answer](https://stackoverflow.com/a/10588594/264697). – Steven Jul 06 '14 at 16:42

1 Answers1

2

The way I do it, and have seen done other places, is to either commit in your business layer, or in your controller, after each transaction. That means sometimes SaveChanges() will be called more than once per request, but that shouldn't be a significant problem.

I've learned a lot from looking at the code for SocialGoal, which can be found here. It uses Autofac for DI, but it's the same principles as your own code. Maybe you can get some inspiration and answers there too.

Tobias
  • 2,811
  • 2
  • 20
  • 31