By default db4o uses JdkReflector(Java) or NetReflector (.NET) as a GenericReflector delegate.
However, the programmer can instruct db4o to use a specially designed reflection implementation:
c#: Db4oFactory.Configure().ReflectWith(reflector)
VB: Db4oFactory.Configure().ReflectWith(reflector)
where reflector is one of the available reflectors or your own reflector implementation.
At present db4o comes with SelfReflector, which was designed for environments, which do not have built-in support for reflections (J2ME for example). In this implementation all the classes' information is stored in special registry. User classes should implement self_get and self_set methods to be registered individually and become "known" to SelfReflector.
Specific reflectors can be written for special usecases.
Let's look how to create a reflector. Remember that db4o relies on reflector to read the database, so errors in reflector may prevent your database from opening.
To keep things simple we will write a LoggingReflector, its only difference from standard reflector is that information about loaded classes is outputted to console. All reflectors used by db4o should implement com.db4o.reflect.Reflector interface.
01/* Copyright (C) 2005 db4objects Inc. http://www.db4o.com */ 02
using System; 03
using Sharpen.Lang ; 04
05
namespace Db4objects.Db4odoc.Reflections 06
{ 07
public class LoggingReflector : Db4objects.Db4o.Reflect.IReflector 08
{ 09
private LoggingArray _arrayHandler; 10
private Db4objects.Db4o.Reflect.IReflector _parent; 11
12
public LoggingReflector() 13
{ 14
} 15
16
public virtual Db4objects.Db4o.Reflect.IReflectArray Array() 17
{ 18
if (_arrayHandler == null) 19
{ 20
_arrayHandler = new LoggingArray(_parent); 21
} 22
return _arrayHandler; 23
} 24
25
public virtual bool ConstructorCallsSupported() 26
{ 27
return true; 28
} 29
30
public virtual Db4objects.Db4o.Reflect.IReflectClass ForName(string className) 31
{ 32
System.Type clazz = null; 33
try 34
{ 35
clazz = TypeReference.FromString(className).Resolve(); 36
} 37
catch (System.Exception) 38
{ 39
} 40
Db4objects.Db4o.Reflect.IReflectClass rc = clazz == null 41
? null 42
: new Db4objects.Db4o.Reflect.Net.NetClass(_parent, clazz); 43
Console.WriteLine("ForName: " + clazz + " -> " + (rc == null ? "" : rc.GetName())); 44
return rc; 45
} 46
47
public virtual Db4objects.Db4o.Reflect.IReflectClass ForObject(object a_object) 48
{ 49
if (a_object == null) 50
{ 51
return null; 52
} 53
Db4objects.Db4o .Reflect .IReflectClass rc = _parent.ForClass(a_object.GetType()); 54
Console.WriteLine("ForObject:" + a_object+" -> "+(rc== null ? "" : rc.GetName())); 55
return rc; 56
} 57
58
public virtual bool IsCollection(Db4objects.Db4o.Reflect.IReflectClass candidate) 59
{ 60
bool result = false; 61
if (candidate.IsArray()) 62
{ 63
result = false; 64
} 65
if (typeof(System.Collections.ICollection).IsAssignableFrom( 66
((Db4objects.Db4o.Reflect.Net.NetClass)candidate).GetNetType())) 67
{ 68
result = true; 69
} 70
Console.WriteLine("Type " + candidate.GetName () + " is Collection " + result); 71
return result; 72
} 73
74
public virtual object DeepClone(object context) 75
{ 76
return new LoggingReflector(); 77
} 78
79
public Db4objects.Db4o.Reflect.IReflectClass ForClass(Type clazz) 80
{ 81
Db4objects.Db4o.Reflect.IReflectClass rc = new Db4objects.Db4o.Reflect.Net.NetClass(_parent, clazz); 82
Console.WriteLine("ForClass: " + clazz + " -> " + (rc == null ? "" : rc.GetName())); 83
return rc; 84
} 85
86
public void SetParent(Db4objects.Db4o.Reflect.IReflector reflector) 87
{ 88
_parent = reflector; 89
} 90
91
} 92
}
01' Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com 02
Imports System 03
Imports Db4objects.Db4o.Reflect 04
Imports Db4objects.Db4o.Reflect.Net 05
06
Namespace Db4objects.Db4odoc.Reflections 07
Public Class LoggingReflector 08
Implements IReflector 09
Private _arrayHandler As LoggingArray 10
Private _parent As IReflector 11
12
Public Sub New() 13
End Sub 14
15
Public Overridable Function Array() As IReflectArray Implements IReflector.Array 16
If _arrayHandler Is Nothing Then 17
_arrayHandler = New LoggingArray(_parent) 18
End If 19
Return _arrayHandler 20
End Function 21
22
Public Overridable Function ConstructorCallsSupported() As Boolean Implements IReflector.ConstructorCallsSupported 23
Return True 24
End Function 25
26
Public Overridable Function ForClass(ByVal clazz As System.Type) As IReflectClass Implements IReflector.ForClass 27
Dim rc As IReflectClass = New NetClass(_parent, clazz) 28
If rc Is Nothing Then 29
Console.WriteLine("ForClass: " + clazz.FullName + " -> ... ") 30
Else 31
Console.WriteLine("ForClass: " + clazz.FullName + " -> " + (rc.GetName())) 32
End If 33
Return rc 34
End Function 35
36
Public Overridable Function ForName(ByVal className As String) As IReflectClass Implements IReflector.ForName 37
Dim clazz As System.Type = Nothing 38
Try 39
clazz = Sharpen.Lang.TypeReference.FromString(className).Resolve() 40
41
Catch e As System.TypeLoadException 42
Return Nothing 43
End Try 44
45
Dim rc As IReflectClass = ForClass(clazz) 46
If rc Is Nothing Then 47
Console.WriteLine("ForName: " + clazz.FullName + " -> ... ") 48
Else 49
Console.WriteLine("ForName: " + clazz.FullName + " -> " + (rc.GetName())) 50
End If 51
Return rc 52
53
End Function 54
55
Public Overridable Function ForObject(ByVal a_object As Object) As IReflectClass Implements IReflector.ForObject 56
If a_object Is Nothing Then 57
Return Nothing 58
End If 59
Dim rc As IReflectClass = _parent.ForClass(a_object.GetType()) 60
If rc Is Nothing Then 61
Console.WriteLine("ForObject: " + a_object.ToString + " -> ... ") 62
Else 63
Console.WriteLine("ForObject: " + a_object.ToString + " -> " + (rc.GetName())) 64
End If 65
Return rc 66
End Function 67
68
Public Overridable Function IsCollection(ByVal candidate As IReflectClass) As Boolean Implements IReflector.IsCollection 69
Dim result As Boolean = False 70
If (candidate.IsArray()) Then 71
result = False 72
End If 73
If (GetType(System.Collections.ICollection).IsAssignableFrom((CType(candidate, NetClass).GetNetType()))) Then 74
result = True 75
End If 76
Console.WriteLine("Type " + candidate.GetName() + " isCollection: " + result.ToString()) 77
Return result 78
End Function 79
80
Public Overridable Sub SetParent(ByVal reflector As IReflector) Implements IReflector.SetParent 81
_parent = reflector 82
End Sub 83
84
Public Overridable Function DeepClone(ByVal context As Object) As Object Implements IReflector.DeepClone 85
Return New LoggingReflector() 86
End Function 87
End Class 88
End Namespace
It is easy to see that this reflector provides the same functionality as JdkReflector or NetReflector extended by console output. The following simple test will show how it works:
01private static void TestReflector() 02
{ 03
IConfiguration configuration = Db4oFactory.NewConfiguration(); 04
LoggingReflector logger = new LoggingReflector(); 05
configuration.ReflectWith(logger); 06
IObjectContainer db = Db4oFactory.OpenFile(configuration, Db4oFileName); 07
try 08
{ 09
Car car = new Car("BMW"); 10
IReflectClass rc = db.Ext().Reflector().ForObject(car); 11
Console.WriteLine("Reflected class: " + rc); 12
} 13
finally 14
{ 15
db.Close(); 16
} 17
}
01Public Shared Sub TestReflector() 02
Dim logger As LoggingReflector = New LoggingReflector() 03
Dim configuration As IConfiguration = Db4oFactory.NewConfiguration() 04
configuration.ReflectWith(logger) 05
Dim db As IObjectContainer = Db4oFactory.OpenFile(configuration, Db4oFileName) 06
Try 07
Dim car As Car = New Car("BMW") 08
Dim rc As IReflectClass 09
rc = db.Ext().Reflector().ForObject(car) 10
Console.WriteLine("Reflected class: " + rc.GetName()) 11
Finally 12
db.Close() 13
End Try 14
End Sub
The output can help you to track all the loaded classes.
Reflection is a powerful tool, which plays a fundamental role in db4o. Understanding reflection will help you to understand the whole db4o functionality in detail.