11

I want to use RavenDB with ninject in my asp.net mvc3 project, Any idea how I have to configure this?

      kernel.Bind<Raven.Client.IDocumentSession>()
              .To<Raven.Client.Document.DocumentStore>()
              .InSingletonScope()
              .WithConstructorArgument("ConnectionString", ConfigurationManager.ConnectionStrings["RavenDB"].ConnectionString);
Jedi Master Spooky
  • 5,629
  • 13
  • 57
  • 86

2 Answers2

25

Here's how I do mine:

If you install Ninject with Nuget, you'll get an /App_start/ NinjectMVC3.cs file. In there:

    private static void RegisterServices(IKernel kernel)
    {            
        kernel.Load<RavenModule>();
    }    

Here's the RavenModule class:

public class RavenModule : NinjectModule
{
    public override void Load()
    {
        Bind<IDocumentStore>()
            .ToMethod(InitDocStore)
            .InSingletonScope();

        Bind<IDocumentSession>()
            .ToMethod(c => c.Kernel.Get<IDocumentStore>().OpenSession())
            .InRequestScope();
    }

    private IDocumentStore InitDocStore(IContext context)
    {
        DocumentStore ds = new DocumentStore { ConnectionStringName = "Raven" };
        RavenProfiler.InitializeFor(ds);
        // also good to setup the glimpse plugin here            
        ds.Initialize();
        RavenIndexes.CreateIndexes(ds);
        return ds;
    }
}

And for completeness here's my index creation class:

public static class RavenIndexes
{
    public static void CreateIndexes(IDocumentStore docStore)
    {
        IndexCreation.CreateIndexes(typeof(RavenIndexes).Assembly, docStore);
    }

    public class SearchIndex : AbstractMultiMapIndexCreationTask<SearchIndex.Result>
    {
       // implementation omitted
    }
}

I hope this helps!

Ronnie Overby
  • 45,287
  • 73
  • 267
  • 346
  • +1 Ninject makes it easy to do session per request as answered using InRequestScope() http://bit.ly/HJADY3 – DalSoft Apr 16 '12 at 11:17
  • Where do you call SaveChanges()? I tried to do it in Application_EndRequest with no luck. – Andrew Sep 03 '12 at 09:52
  • I call SaveChanges() explicitly when it makes sense to do so, not automatically at the end of each request. I'm not sure why you need to do that or why you're having problems. I suspect it has something to do with Ninject's order of operations with request scoped dependencies, though there's no telling without some diagnostic information. – Ronnie Overby Sep 03 '12 at 13:11
7

I recommend using a custom Ninject Provider to set up your RavenDB DocumentStore. First place this in your code block that registers your Ninject services.

kernel.Bind<IDocumentStore>().ToProvider<RavenDocumentStoreProvider>().InSingletonScope();

Next, add this class that implements the Ninject Provider.

public class RavenDocumentStoreProvider : Provider<IDocumentStore>
{
  var store = new DocumentStore { ConnectionName = "RavenDB" };
  store.Conventions.IdentityPartsSeparator = "-"; // Nice for using IDs in routing
  store.Initialize();
  return store;
}

The IDocumentStore needs to be a singleton, but do not make the IDocumentSession a singleton. I recommend that you simply create a new IDocumentSession using OpenSession() on the IDocumentStore instance Ninject gives you whenever you need to interact with RavenDB. IDocumentSession objects are very lightweight, follow the unit-of-work pattern, are not thread-safe, and are meant to be used and quickly disposed where needed.

As others have done, you might also consider implementing a base MVC controller that overrides the OnActionExecuting and OnActionExecuted methods to open a session and save changes, respectively.

reverentgeek
  • 101
  • 1
  • 3