You are here: Platform Specific Issues > Web Environment > ASP.NET Request Example

ASP.NET Request Example

This example demonstrates how you can provide an object container for each request, to ensure that the requests are isolated from each other. For this we use session object containers. See "Isolation in Web-Applications"

First, create a new class which implements the IHttpModule-interface. Then register this interface in the Web.config configuration:

<httpModules>
  <add name="Db4oDatabase" type="Db4oDoc.WebApp.Infrastructure.Db4oProvider" />
  <!-- Other, existing modules-->
  <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</httpModules>
Web.config: Add the db4o-http-handler

Additionally add a key where you specify the path to the database-file. Make sure that you have the data folder inside you web-site directory. The ASP.NET user should have enough rights to create and modify files inside this folder. You should also make sure that the data folder is not accessible to anonymous user; otherwise web-server visitors will be able to download your database:

<appSettings>
  <add key="DatabaseFileName" value="~/App_Data/database.db4o"/>
</appSettings>
Web.config: Database path in the configuration

After that, implement the initializing sequence. When the server starts, it starts up db4o and adds the database to the application-context:

public void Init(HttpApplication context)
{
    if (null == HttpContext.Current.Application[DataBaseInstance])
    {
        HttpContext.Current.Application[DataBaseInstance] = OpenDatabase();
    }
    RegisterSessionCreation(context);
}

private IEmbeddedObjectContainer OpenDatabase()
{
    string relativePath = ConfigurationSettings.AppSettings["DatabaseFileName"];
    string filePath = HttpContext.Current.Server.MapPath(relativePath);
    return Db4oEmbedded.OpenFile(filePath);
}
Db4oProvider.cs: open database when the application starts

On the dispose-method add the shutdown code:

public void Dispose()
{
    IDisposable toDispose = HttpContext.Current.Application[DataBaseInstance] as IDisposable;
    if (null != toDispose)
    {
        toDispose.Dispose();
    }
}
Db4oProvider.cs: close the database when the application shuts down

Now it's time to ensure that each requests has its own object container. To archive that, use the open-session-method. Register for the request-begin and request-end events. In begin session event, open a new db4o session. In the end request event, close that session.

private void RegisterSessionCreation(HttpApplication httpApplication)
{
    httpApplication.BeginRequest += OpenSession;
    httpApplication.EndRequest += CloseSession;
}

private void OpenSession(object sender, EventArgs e)
{
    IObjectContainer container =
        (IObjectContainer)HttpContext.Current.Application[DataBaseInstance];
    IObjectContainer session = container.Ext().OpenSession();
    HttpContext.Current.Items[SessionKey] = session;
}

private void CloseSession(object sender, EventArgs e)
{
    IObjectContainer session = (IObjectContainer)HttpContext.Current.Items[SessionKey];
    session.Dispose();
}
Db4oProvider.cs: A object container per request

Finally add a static property which gives access to the request-instance:

public static IObjectContainer Database
{
    get { return (IObjectContainer)HttpContext.Current.Items[SessionKey]; }
}
Db4oProvider.cs: provide access to the database

That's it. Of course there are other ways to archive the same result. For example you can use dependency injection frameworks like Microsoft's Unity to enforce the request scope.