2

I have started coding a small ASP.NET MVC 4 project. So far there isn't a front end, however, as I started with the API my project will expose. The API is created using Web API's API controllers. The API controllers access data stored in a Raven DB database. When debugging my code using VS 2012 and IIS Express, everything works fine. During the first request, that is. In the second request, the Raven DB IDocumentStore object (i.e. the database connection object) has been disposed and I have no idea how it happened.

I use Ninject to inject the IDocumentStore object into my repository objects and Ninject is setup like this:

public class NinjectModule: Ninject.Modules.NinjectModule {
    readonly string _connStrName;

    IDocumentStore _store;

    public NinjectModule(string connStrName) {
        _connStrName = connStrName;
    }

    public override void Load() {
        _store = new DocumentStore { ConnectionStringName = _connStrName };
        _store.Initialize();

        Bind<IDocumentStore>().ToConstant(_store);
    }

    public override void Unload() {
        _store.Dispose();

        base.Unload();
    }
}

The IDocumentStore is disposed in the Unload method but, as far as I can tell, the Unload method is never called.

It would be great if someone could tell me why my IDocumentStore gets disposed but I'll settle for a way to debug when it actually gets disposed. Can I trigger when a specific object is disposed?

I have checked very carefully and the IDocumentStore object is never disposed by my (still very small) code base.

mipe34
  • 5,596
  • 3
  • 26
  • 38
David Nordvall
  • 12,404
  • 6
  • 32
  • 52
  • Why can't you just put breakpoint inside `IDocumentStore.Dispose()` method and then look on the call stack from where it is called. However, my suggestion is to bind `IDocumentStore` `InRequestScope()` and use `OnePerRequestModule` to make it working. It will create your object on HTTP request and dispose it automatically at the end. Holding one DB connection for whole application life is not a good idea, it could lead to concurrency and performance issues. – mipe34 Jan 23 '13 at 21:11
  • @mipe34 an `IDocumentStore` is a singleton. See my answer. – Matt Johnson-Pint Jan 23 '13 at 23:40
  • mipe34: Is it possible to add breakpoints in methods where I don't have any source code? If so, how? I don't have the code for the IDocumentStore implementation. Well, Raven DB is open source so I guess I could build it my self but I'd rather not... – David Nordvall Jan 24 '13 at 06:55
  • @David Nodrvall: My bad. I didn`t know, that `DocumentStore` is not yours. However just for debugging purposes, you can write a tiny wrapper around `DocumentStore` that implements `IDocumentStore`, and uses `DocumentStore` object. Then bind it to Ninject the same way as you did with `DocumentStore` and look when it is being disposed. – mipe34 Jan 24 '13 at 09:37
  • I believe this is the same question as [here](http://stackoverflow.com/questions/4611832/ninject-problem-binding-to-constant-value-in-mvc3-with-a-ravendb-session). See [this](http://stackoverflow.com/questions/5145775/ninject-doesnt-call-dispose-on-objects-when-out-of-scope) also. – Matt Johnson-Pint Jan 24 '13 at 14:39
  • @MattJohnson That is a question regering ninject binding of the document _session_ and my question is regarding the document _store_. – David Nordvall Jan 24 '13 at 17:12
  • Yes, but the answer of using `ToMethod` instead of `ToConstant` is probably the same. Did you try it? – Matt Johnson-Pint Jan 24 '13 at 17:31

1 Answers1

0

I'm not sure if this is the problem or not, but a RavenDB IDocumentStore should have a single-instance lifetime scope, while a IDocumentSession should have a per-request scope.

I use AutoFac myself, but a quick search for how to define lifetime scopes in Ninject yielded this page.

Please try adding .InSingletonScope() where appropriate for the IDocumentStore and see if that solves the problem.

If you are going to use Ninject for your session, then it looks like .InRequestScope() would be the appropriate option there.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • I've already considered this. The Bind().ToConstant(_store) call makes all requests for an instance of IDocumentStore return the _store instance. Effectively making it a singleton. And I've also tried to add the InSingletonScope() call just to be sure but it made no difference. – David Nordvall Jan 24 '13 at 06:14