In a number of articles last fall on my personal blog 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 post, I will demonstrate how RavenDB can be used as the Data Store for a DotNetNuke Module. (I will assume that readers are familiar with NoSQL Databases and RavenDB in particular, but if you are not familiar then please read those earlier articles)
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; }
}
|
The first point to note is that Raven expects our “key” field to be called Id and it also assumes it is a string. 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
|
|
RavenDB comes in two flavors - 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
|
|
In the Package Manager dialog enter RavenDB to get a list of RavenDB packages (Figure 3).
Figure 4: Install RavenDB using NuGet
|
|
Select the RavenDB Embedded package 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 that for this connectionString to work 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 url, 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. This is a very simple example. We could improve it by avoiding getting a new Document Store every time, by using a Service Location or Dependency Injection Container. But, it is clear from this example that using RavenDB is very easy.
This post is reproduced from my personal blog (with some modification)