<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" MadCap:lastBlockDepth="2" MadCap:lastHeight="120" MadCap:lastWidth="624" MadCap:disableMasterStylesheet="true" MadCap:tocPath="Advanced Features|Type Handling" MadCap:InPreviewMode="false" MadCap:RuntimeFileType="Topic" MadCap:TargetType="WebHelp" MadCap:PathToHelpSystem="../../../" MadCap:HelpSystemFileName="index.xml" MadCap:SearchType="Stem"> <head><title>Translators</title> <script type="text/javascript">/* <![CDATA[ */ window.onload = function(){ var pathToFlash = $('html').attr('MadCap:PathToHelpSystem') + 'Content/Resources/Code/ZeroClipboard.swf'; ZeroClipboard.setMoviePath(pathToFlash); function bindToClipBord(element,content){ var clip = new ZeroClipboard.Client(); clip.setText(content); clip.glue(element); }; if(location.protocol==='file:'){ $('.copylink-marker').remove(); } else{ $('.copylink-marker').each(function(){ var text = $(this).parent().parent().children('.prettyprint').html(); $(this).hover(function(){ bindToClipBord(this,text); }, function(){}); }); } prettyPrint(); }; /* ]]> */</script> <link href="../../SkinSupport/MadCap.css" rel="stylesheet" /> <link href="../../Resources/Stylesheets/OnlineStyle.css" rel="stylesheet" /> <script src="../../Resources/Code/prettify.js"> </script> <script src="../../Resources/Code/lang-vb.js"> </script> <script src="../../Resources/Code/jquery.min.js"> </script> <script src="../../Resources/Code/ZeroClipboard.js"> </script> <script src="../../SkinSupport/MadCapAll.js" type="text/javascript"> </script> </head> <body> <p class="MCWebHelpFramesetLink" style="display: none;"><a href="../../../index_CSH.html#advanced_topics/type_handling/translators.htm" style="">Open topic with navigation</a> </p> <div class="MCBreadcrumbsBox"><span class="MCBreadcrumbsPrefix">You are here: </span><a class="MCBreadcrumbsLink" href="../../advanced_topics.htm">Advanced Features</a><span class="MCBreadcrumbsDivider"> > </span><a class="MCBreadcrumbsLink" href="../type_handling.htm">Type Handling</a><span class="MCBreadcrumbsDivider"> > </span><span class="MCBreadcrumbs">Translators</span> </div> <p> <script type="text/javascript">/*<![CDATA[*/document.write('<a href="' + location.href +'">'); document.write("Direct Link"); document.write('</a>');/*]]>*/</script> </p> <p> </p> <h1><a name="kanchor87"></a>Translators</h1> <p>Sometimes objects cannot be stored in db4o. For example because the objects have references to other parts of the system other where never intended to be stored. This is especially for objects from third party libraries. </p> <p>Now the db4o object translators is a simple mechanism which allows you to manually handle the persistence of an object. There are two important interfaces for this. The <span MadCap:conditions="Primary..NET">I</span>ObjectTranslator-interface and the <span MadCap:conditions="Primary..NET">I</span>ObjectConstructor. The first interface lets you take the control over storing and activation of the object. The second interface also allows you to control the instantiation of the object.</p> <p>If you register a <span MadCap:conditions="Primary..NET">I</span>ObjectTranslator-instance for a certain type, it will also be applied to sub-types. This doesn't apply to <span MadCap:conditions="Primary..NET">I</span>ObjectConstructor-instances, because those need to create the right instance and therefore cannot handle subtypes.</p> <h2>Creating a Translator</h2> <p>First you need to create a translator for your types. Let's take a look at this example. There three distinct tasks a translator has to do. The first task is to convert the not storable object into another, storable object. Another task of the translator is to take care of the activation of the object. There it need to copy the values from the stored object into a instance of the original type. The third task it to create instances of the object. There you create a instance of the original type. And for some types you maybe also read the data at this point in time. </p> <div class="codesnippet" MadCap:conditions="Primary.c#"> <pre class="prettyprint" xml:space="preserve">internal class ExampleTranslator : IObjectConstructor { // This is called to store the object public Object OnStore(IObjectContainer objectContainer, Object objToStore) { NonStorableType notStorable = (NonStorableType) objToStore; return notStorable.Data; } // This is called when the object is activated public void OnActivate(IObjectContainer objectContainer, Object targetObject, Object storedObject) { NonStorableType notStorable = (NonStorableType) targetObject; notStorable.Data = (String) storedObject; } // Tell db4o which type we use to store the data public Type StoredClass() { return typeof (String); } // This method is called when a new instance is needed public Object OnInstantiate(IObjectContainer objectContainer, Object storedObject) { return new NonStorableType(""); } } </pre> <div class="codesnippet-meta">ExampleTranslator.cs: An example translator <div class="codedownload"><a href="../../CodeExamples/typehandling/translator/Example-typehandling-translator-csharp.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div> </div> <div class="codesnippet" MadCap:conditions="Primary.VB.NET"> <pre class="prettyprint lang-vb" MadCap:conditions="Primary.Online" xml:space="preserve">Friend Class ExampleTranslator Implements IObjectConstructor ' This is called to store the object Public Function OnStore(ByVal objectContainer As IObjectContainer, _ ByVal objToStore As Object) As Object _ Implements IObjectConstructor.OnStore Dim notStorable As NonStorableType = DirectCast(objToStore, NonStorableType) Return notStorable.Data End Function ' This is called when the object is activated Public Sub OnActivate(ByVal objectContainer As IObjectContainer, _ ByVal targetObject As Object, ByVal storedObject As Object) _ Implements IObjectConstructor.OnActivate Dim notStorable As NonStorableType = DirectCast(targetObject, NonStorableType) notStorable.Data = DirectCast(storedObject, String) End Sub ' Tell db4o which type we use to store the data Public Function StoredClass() As Type _ Implements IObjectConstructor.StoredClass Return GetType(String) End Function ' This method is called when a new instance is needed Public Function OnInstantiate(ByVal objectContainer As IObjectContainer, _ ByVal storedObject As Object) As Object _ Implements IObjectConstructor.OnInstantiate Return New NonStorableType("") End Function End Class</pre> <div class="codesnippet-meta">ExampleTranslator.vb: An example translator <div class="codedownload"><a href="../../CodeExamples/typehandling/translator/Example-typehandling-translator-vb.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div> </div> <h2>Registering a Translator</h2> <p>After that you can register the translator for you're type. If you register a <span MadCap:conditions="Primary..NET">I</span>ObjectTranslator-instance it will also be applied to the sub-types. However a <span MadCap:conditions="Primary..NET">I</span>ObjectConstructor-instance is only applied for the specific type. </p> <div class="codesnippet" MadCap:conditions="Primary.c#"> <pre class="prettyprint" xml:space="preserve">IEmbeddedConfiguration configuration = Db4oEmbedded.NewConfiguration(); configuration.Common.ObjectClass(typeof(NonStorableType)).Translate(new ExampleTranslator()); IObjectContainer container = Db4oEmbedded.OpenFile(configuration, "database.db4o");</pre> <div class="codesnippet-meta">ExampleTranslator.cs: Register type translator for the NonStorableType-class <div class="codedownload"><a href="../../CodeExamples/typehandling/translator/Example-typehandling-translator-csharp.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div> </div> <div class="codesnippet" MadCap:conditions="Primary.VB.NET"> <pre class="prettyprint lang-vb" MadCap:conditions="Primary.Online" xml:space="preserve">Dim configuration As IEmbeddedConfiguration = Db4oEmbedded.NewConfiguration() configuration.Common.ObjectClass(GetType(NonStorableType)).Translate(New ExampleTranslator()) Dim container As IObjectContainer = Db4oEmbedded.OpenFile(configuration, "database.db4o")</pre> <div class="codesnippet-meta">ExampleTranslator.vb: Register type translator for the NonStorableType-class <div class="codedownload"><a href="../../CodeExamples/typehandling/translator/Example-typehandling-translator-vb.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div> </div> <h2>Using The Translator</h2> <p>After that you can store and use the not storable objects like any other persistent objects. db4o will call the translator for each instance when required in order to store the object correctly. </p> <div class="codesnippet" MadCap:conditions="Primary.c#"> <pre class="prettyprint" xml:space="preserve">container.Store(new NonStorableType("TestData"));</pre> <div class="codesnippet-meta">ExampleTranslator.cs: Store the non storable type <div class="codedownload"><a href="../../CodeExamples/typehandling/translator/Example-typehandling-translator-csharp.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div> </div> <div class="codesnippet" MadCap:conditions="Primary.VB.NET"> <pre class="prettyprint lang-vb" MadCap:conditions="Primary.Online" xml:space="preserve">container.Store(New NonStorableType("TestData"))</pre> <div class="codesnippet-meta">ExampleTranslator.vb: Store the non storable type <div class="codedownload"><a href="../../CodeExamples/typehandling/translator/Example-typehandling-translator-vb.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div> </div> <div class="codesnippet" MadCap:conditions="Primary.c#"> <pre class="prettyprint" xml:space="preserve">NonStorableType data = container.Query<NonStorableType>()[0];</pre> <div class="codesnippet-meta">ExampleTranslator.cs: Load the non storable type <div class="codedownload"><a href="../../CodeExamples/typehandling/translator/Example-typehandling-translator-csharp.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div> </div> <div class="codesnippet" MadCap:conditions="Primary.VB.NET"> <pre class="prettyprint lang-vb" MadCap:conditions="Primary.Online" xml:space="preserve">Dim data As NonStorableType = container.Query(Of NonStorableType)()(0)</pre> <div class="codesnippet-meta">ExampleTranslator.vb: Load the non storable type <div class="codedownload"><a href="../../CodeExamples/typehandling/translator/Example-typehandling-translator-vb.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div> </div> <h2>Limitations</h2> <p>The object translator mechanism is great for types which couldn't be stored otherwise. However there are serious limitations.</p> <ul> <li value="1">Queries into the members of a object which was stored with a object translator are extremely slow. The reason is that the object first need to be loaded and instantiated with the translator in order to run the query on it. </li> <li value="2">You cannot index types which are translated.</li> </ul> <script type="text/javascript" src="../../SkinSupport/MadCapBodyEnd.js"> </script> </body> </html>