Class Name Format In .NET

Db4o uses full class name to distinguish classes within the database file. In .NET full class name has the following format:

Namespace.ClassName, AssemblyName

Effectively that means that the same class definition within different assemblies (applications or libraries) will be recognized as two different classes by db4o. You should keep this in mind in the following cases:

Let's use an example to see what happens in these cases. We will create 2 applications Test1.exe and Test2.exe. Both will have a simplest class definition:

Test.cs
01/* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com */ 02namespace Db4objects.Db4odoc.ClassNameFormat 03{ 04 class Test 05 { 06 public override string ToString() 07 { 08 return "Test"; 09 } 10 } 11}

Test.vb
01' Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com 02Namespace Db4objects.Db4odoc.ClassNameFormat 03 04 Class Test 05 06 Public Overloads Overrides Function ToString() As String 07 Return "Test" 08 End Function 09 End Class 10End Namespace

Test1 application will store one object of Test class to the database:

ClassNameExample1.cs: StoreObjects
01public static void StoreObjects() 02 { 03 File.Delete(YapFileName); 04 IObjectContainer container = Db4oFactory.OpenFile(YapFileName); 05 try 06 { 07 // Store a simple class to the database 08 Test test = new Test(); 09 container.Set(test); 10 } 11 finally 12 { 13 container.Commit(); 14 } 15 }

ClassNameExample1.vb: StoreObjects
01Public Shared Sub StoreObjects() 02 File.Delete(YapFileName) 03 Dim container As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 04 Try 05 ' Store a simple class to the database 06 Dim test As Test = New Test 07 container.Set(test) 08 Finally 09 container.Commit() 10 End Try 11 End Sub

Another application (Test2) will try to read this object from the same database file. To check how  the Test object was actually stored in the database we will use StoredClass API:

ClassNameExample2.cs: CheckDatabase
01public static void CheckDatabase() 02 { 03 IObjectContainer container = Db4oFactory.OpenFile(YapFileName); 04 try 05 { 06 // Read db4o contents from another application 07 IObjectSet result = container.Get(typeof(Test)); 08 ListResult(result); 09 // Check what classes are actualy stored in the database 10 IStoredClass[] storedClasses = container.Ext().StoredClasses(); 11 for (int i = 0; i < storedClasses.Length; i++) 12 { 13 System.Console.WriteLine("Stored class: " + storedClasses[i].GetName()); 14 } 15 } 16 finally 17 { 18 container.Commit(); 19 } 20 }

ClassNameExample2.vb: CheckDatabase
01Public Shared Sub CheckDatabase() 02 Dim container As IObjectContainer = Db4oFactory.OpenFile(YapFileName) 03 Try 04 ' Read db4o contents from another application 05 Dim result As IObjectSet = container.Get(GetType(Test)) 06 ListResult(result) 07 ' Check what classes are actualy stored in the database 08 Dim storedClasses As IStoredClass() = container.Ext.StoredClasses 09 Dim i As Integer = 0 10 While i < storedClasses.Length 11 System.Console.WriteLine("Stored class: " + storedClasses(i).GetName) 12 System.Math.Min(System.Threading.Interlocked.Increment(i), i - 1) 13 End While 14 Finally 15 container.Commit() 16 End Try 17 End Sub

From the example we can see that though the class has been stored to the database, it cannot be retrieved from the Test2 application, as the assembly name is different from the original.

In order to make your classes readable from another assembly you should use one of the existing workarounds:

  • keep your persistent classes in a separate class library, which should be available for your application assemblies (for the example above compile the Test class into Persistent.dll);
  • use db4o Aliases.