Creating your own reflector

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.

LoggingReflector.cs
01/* Copyright (C) 2005 db4objects Inc. http://www.db4o.com */ 02using System; 03using Sharpen.Lang ; 04 05namespace 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}
LoggingReflector.vb
01' Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com 02Imports System 03Imports Db4objects.Db4o.Reflect 04Imports Db4objects.Db4o.Reflect.Net 05 06Namespace 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 88End Namespace

[/filter]

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:

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.