0

My project is using MVC5, EF6 and Ninject.

I have some service classes which composes the business layer, and only them are allowed to access the DbContext, meaning that the controller doesn't have any direct access to the context.

The service classes are like those:

public interface IService1: IDisposable
{
    IEnumerable<SomeDataType> GetSomeData(string param);
    void SaveData();
}
public class Service1: IService1
{
    private MyContext context;

    public Maestri(MyContext context)
    {
        this.context = context;
    }

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

    public IEnumerable<SomeDataType> GetSomeData(string Param)
    {
        [...]
    }

    public void SaveData()
    {
        [...]
        context.SaveChanges()
    }
}

public interface IService2: IDisposable
{
    IEnumerable<SomeDataType2> GetSomeData(string param);
    void SaveData();
}
public class Service2: IService2
{
    private MyContext context;

    public Maestri(MyContext context)
    {
        this.context = context;
    }

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

    public IEnumerable<SomeDataType2> GetSomeData(string Param)
    {
        [...]
    }

    public void SaveData()
    {
        [...]
        context.SaveChanges()
    }
}

In Ninject CreateKernel are initialized like this:

kernel.Bind<MyContext>().ToSelf().InRequestScope();                
kernel.Bind<IService1>().To<Service1>().InRequestScope();
kernel.Bind<IService2>().To<Service2>().InRequestScope();

In the controller:

public class MyController : Controller
{
    private readonly IService1 _service1;
    private readonly IService2 _service2;

    public MyController(IService1 service1, IService2 service2)
    {
        _service1 = service1;
        _service2 = service2;
    }

    public ActionResult SomeAction()
    {
        var data1 = _service1.GetSomeData("");
        var data2 = _service2.GetSomeData("");

        [...]

        return View(); 
    }
}

I've noticed that for every request to Controller/SomeAction the MyContext constructor has called only once, but the dispose() will be called twice. This leads me to think about a bad design of mine. I've tried to remove the context.Dispose(); from the services, but this leads to MyContext.dispose to never get called, but a new instance is generated for every request. Could someone please point me out what am I doing wrong?

Thanks!

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Kiske1
  • 408
  • 3
  • 15
  • If you dispose the context in Service1, it seems normal, as ninject should dispose the registered objects either. So I guess you can remove the context.dispose() from your service – Laurent Lequenne Jun 27 '17 at 07:53
  • But ninject never calls dispose on the context, some someone else should call it I think – Kiske1 Jun 27 '17 at 08:05
  • What will be the use of injection ? How can you know that the context you are disposing xould not be used by another service ? It's obvious that ninject should dispose the objects he has created... If not you should use another IOC framework :) – Laurent Lequenne Jun 27 '17 at 08:47
  • I totally agree, but putting a breakpoint on the DbContext _Dispose()_ method it never gets called. I really can't think that Ninject "forgets" about the context ;) – Kiske1 Jun 27 '17 at 08:52
  • Are you sure that MyContext has the IDisposable interface ? – Laurent Lequenne Jun 27 '17 at 09:00
  • I didn't see the full code... you are disposing the context also in Service2 , so that's totally a normal behavior related to your implementation, regardless the fact the ninject does not dispose that object himself which is weird... Maybe there is something wrong with your ninject object registration... – Laurent Lequenne Jun 27 '17 at 09:07
  • 1
    https://stackoverflow.com/questions/27312389/cant-get-ninject-to-dispose-object-in-request-scope – Laurent Lequenne Jun 27 '17 at 09:08
  • Yes, because it's a DbContext, wich I'm sure implements IDisposable. – Kiske1 Jun 27 '17 at 09:09
  • Check the previous link, it's related to a bug in ninject :-) – Laurent Lequenne Jun 27 '17 at 09:17
  • Yeah! There was the problem! Updating ninject components to the latest stable made disposing behave normally. Thank you! – Kiske1 Jun 27 '17 at 09:19
  • So please remove your context.dispose() in your services haahha :-) – Laurent Lequenne Jun 27 '17 at 09:21
  • @LaurentLequenne please post as an answer or we should close this question as a dupe – Dave Thieben Jun 28 '17 at 12:22
  • @davethieben go for it :) – Laurent Lequenne Jun 28 '17 at 14:04

0 Answers0