db40 on shared hosting love
I’m tired of fighting the ORM battle, L2S, SubSonic, NHibernate, Lightspeed, etc. They’re all great products but painful to use because they are all “bandages” on the problem of object-relational impedance. So I thought I’d try something different, db4o. db4o is an object database. No tables, no ORM, nada. Just POCO love, it’s like the repository pattern on steroids. My big concerns were licensing costs and the fact that I deploy on a shared host. Both of which were misplaced.
The licensing cost for an In-Process database for commercial use was comparable to a standard ReSharper license. So it’s within the reach of “normal” developers who’d like to use the database for their web application. If you’re writing an open-source application or one that is not for redistribution, then the GPL license will be fine for your purposes. Honestly, I was expecting thousands of dollars for the licensing, as the technology is so impressive.
After finding out that the pricing was within reason I was excited but afraid that it’s all well and good that I can afford it but I’m using shared hosting, so it’s going to be impossible to deploy. Wrong again! The In-Process database only requires a single DLL to function. Let me reiterate that, the entire db4o system is contained in a *single* library that only requires medium trust and the ability to write to a file. So I used some of the demo code provided by db4o and whipped up a little POC to see if this would work on my ReliableSite.net account.
Just add a reference to Db4objects.Db4o.dll and make sure “Copy Local” is set to true.
Define your POCO.
namespace Nuscia.Models
{
public class Person
{
/// <summary>
/// Initializes a new instance of the <see cref="Person"/> class.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="number">The points.</param>
public Person(string name, int number)
{
this.Name = name;
this.Number = number;
}
/// <summary>
/// Gets or sets the points.
/// </summary>
/// <value>The points.</value>
public int Number { get; set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string Name { get; set; }
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
/// </returns>
public override string ToString()
{
return string.Format("{0}/{1}", this.Name, this.Number);
}
}
}
This is a very simplistic example where two objects are created and inserted then selected back from the database. Notice that the In-Process model uses a file store, so you’ll need to specify a directory that has RW+ access.
using (IObjectContainer container = Db4oFactory.OpenFile("C:\\HostingSpaces\\ACCOUNT_NAME\\DOMAIN_NAME.TLD\\data\\MY_DB4O_FILE.db"))
{
container.Store(new Person("Penelope", 100));
container.Store(new Person("Aneta", 200));
IObjectSet results = container.Query(typeof (Person));
foreach (object result in results)
{
this.ViewData["db4o"] += string.Format("{0} ", result);
}
}
That’s it, deploy and run. You can see in my example I was running the snippet directly from my ASP.NET MVC controller, obviously it is POC code and not how you would want to structure your real application. No muss, no fuss, just pure OO persistence goodness out of the box.
[edit: I can't believe I typed db40 as the title!]