Thoughts from the Wet Coast

The musings of an ASP.NET Developer from Canada's We(s)t Coast

Comments

Articles

 
     

Look Mom, NoSQL! - 8. Using RavenDB in a DotNetNuke Module

Category: DataDotNetNuke
Aug 14 2012

In a number of articles last fall I discussed NoSQL Databases in general and showed how RavenDB – a .NET NoSQL Database - could be used as the Data Store for an ASP.NET MVC Application.

In this article, I will demonstrate how RavenDB can be used as the Data Store for a DotNetNuke Module.

First lets assume I have created a Web Application Project for my DotNetNuke Module.  My Module, surprise, surprise, is going to be a Tasks or To-do List module.  A task is defined by the Task class - see Listing 1.

Listing 1: The Model class

public class Task
{
    public string Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public bool IsComplete { get; set; }
}

Our main View Module Control will display a List of Tasks - see Listings 2 and 3.

Listing 2: The TaskList Module Control

Task List

The Html in Listing 2 has been made more readable by removing some of the attributes associated with the styling of the DataGrid (e.g. Column Width, Header Text, etc.

Listing 3: The TaskList Module Control OnLoad method

protected override void OnLoad(System.EventArgs e)
{
    base.OnLoad(e);

    tasksGrid.DataSource = TaskController.Instance.GetTasks();
    tasksGrid.DataBind();
}

The TaskController could be any DotNetNuke Controller class.  I have elected to use the new “Testable” Controller pattern, based on the ServiceLocator base class.  GetTasks returns an IList which is bound to the DataSource of the grid. 

Before I explain how we connect with a RavenDB database lets just look at the resulting Module Control when the module is added to the page.

Figure 1: The Tasks  Module

image

RavenDB comes in two flavours - a server version and an embedded version.  We will use the embedded version and to add RavenDB Embedded to our Module, we will use NuGet (Figure 2). To use Nuget in Visual Studio right-click on the References folder and select “Manage NuGet Packages”.

Figure 2: Adding a new Nuget Package

image

In the Package Manager dialog enter RavenDB to get a list of RavenDB packages (Figure 3).

Figure 4: Install RavenDB using NuGet

image

Select the RavenDB Embedded and click Install to add RavenDB Embedded and any dependencies to your project. (In the image the green check marks show that I have already installed RavenDB in my project).

Everything in RavenDB is accessed through an instance of IDocumentStore, in the case of RavenDB Embedded an  EmbeddableDocumentStore, so we can create a utility method to create our IDocumentStore instance (Listing 4)

Listing 4: CreateDocumentStore method

public static IDocumentStore CreateDocumentStore()
{
    var instance = new EmbeddableDocumentStore
        {
            ConnectionStringName = "RavenDB",
            Conventions = {IdentityPartsSeparator = "-"}
        };
    instance.Initialize();
    return instance;
}

This will create an IDocumentStore instance based on the named Connection String - RavenDB - which we need to add to web.config (Listing 5).  Note we will also need to create the folder - RavenTasks in the Website’s App_Data folder.

Listing 5: RavenDB Connection String


  
  

In Listing 4 I initialized the DocumentStore with its Connection String and a “convention” - I set the IdentityPartsSeparator to “-“. RavenDB identifies items using the plural of the type name and the Id of the object (eg. tasks-123), separated by the IdentityPartsSeparator. The default separator is “/”, which would cause problems if the id is passed in a querystring, so I have elected to use a dash which is safer.

Now that we have installed RavenDB, and configured a Document Store, we can create our methods in the TaskController.

Listing 6: Implementing GetTasks

public IList GetTasks()
{
    IList tasks;
    using (var ds = RavenDocumentStore.CreateDocumentStore())
    {
        using (var session = ds.OpenSession())
        {
            tasks = session.Query().ToList();
        }
    }
    return tasks;
}

To get a list of tasks, we first get our IDocumentStore instance by calling our utility method.  Then using the document store we can open a session to communicate with it.  The Session object’s Query method allows us to get an IEnumerable from the Document Store.  Finally, we ensure that the Session and DocumentStore objects are disposed of by using the using statement.

And that’s it - its pretty easy.  Listing 7 shows the remaining methods necessary to delete, get and save Tasks - it’s a pretty standard Unit of Work pattern.

Listing 7: The remaining methods

public void DeleteTask(string taskId)
{
    using (var documentStore = RavenDocumentStore.CreateDocumentStore())
    {
        using (var session = ds.OpenSession())
        {
            var task = session.Load(taskId);
            session.Delete(task);
            session.SaveChanges();
        }
    }
}

public Task GetTask(string taskId)
{
    Task task;
    using(var ds = RavenDocumentStore.CreateDocumentStore())
    {
        using (var session = ds.OpenSession())
        {
            task = session.Load(taskId);
        }
    }
    return task;
}

public void UpdateTask(Task task)
{
    using (var ds= RavenDocumentStore.CreateDocumentStore())
    {
        using (var session = ds.OpenSession())
        {
            session.Store(task);
            session.SaveChanges();
        }
    }
}

The rest of the module is normal DotNetNuke module development.  In fact the only piece that is different is the implementation of the TaskController class.

Categories

Tags