You are here: Basics Operations & Concepts > Activation > Transparent Activation > Example

Transparent Activation Example

In order to support Transparent Activation, the objects which are stored in the database need to implement the IActivatable-interface.

An object which implements the IActivatable-interface is responsible for activating itself. For this purpose the class needs a field to keep its activator. This field is only used by the transparent activation framework. Therefore it's marked as transient, to avoid that it's stored in the database. 

public class Person : IActivatable
{
    [NonSerialized] private IActivator activator;
Person.cs: Implement the required activatable interface and add activator
Public Class Person
    Implements IActivatable
    <Transient()> _
    Private m_activator As IActivator
Person.vb: Implement the required activatable interface and add activator

Then implement the two methods of the IActivatable-interface. The bind-method binds an activator to the object. It's called by the transparent activation framework. The activate-method needs to be called before any read or write operation on the object. Since these two methods are always the same, you can move the implementation to a common super class or to a static utility class.

public void Bind(IActivator activator)
{
    if (this.activator == activator)
    {
        return;
    }
    if (activator != null && null != this.activator)
    {
        throw new InvalidOperationException("Object can only be bound to one activator");
    }
    this.activator = activator;
}

public void Activate(ActivationPurpose activationPurpose)
{
    if (null != activator)
    {
        activator.Activate(activationPurpose);
    }
}
Person.cs: Implement the activatable interface methods
Public Sub Bind(ByVal activator As IActivator) _
        Implements IActivatable.Bind
    If m_activator Is activator Then
        Exit Sub
    End If
    If activator IsNot Nothing AndAlso m_activator IsNot Nothing Then
        Throw New InvalidOperationException("Object can only be bound to one activator")
    End If
    m_activator = activator
End Sub

Public Sub Activate(ByVal activationPurpose As ActivationPurpose) _
        Implements IActivatable.Activate
    If m_activator IsNot Nothing Then
        m_activator.Activate(activationPurpose)
    End If
End Sub
Person.vb: Implement the activatable interface methods

Now the important part. Every time a field of the class is accessed you need to call the activate-method with the purpose. For example in every property or other method. Probably the best way is to use only property even within the class to access fields. And the property ensures that the activate-method is called.

public string Name
{
    get
    {
        Activate(ActivationPurpose.Read);
        return name;
    }
    set
    {
        Activate(ActivationPurpose.Write);
        name = value;
    }
}


public override string ToString()
{
    // use the getter/setter withing the class,
    // to ensure the activate-method is called
    return Name;
}
Person.cs: Call the activate method on every field access
Public Property Name() As String
    Get
        Activate(ActivationPurpose.Read)
        Return m_name
    End Get
    Set(ByVal value As String)
        Activate(ActivationPurpose.Write)
        m_name = value
    End Set
End Property


Public Overloads Overrides Function ToString() As String
    ' use the getter/setter withing the class,
    ' to ensure the activate-method is called
    Return Name
End Function
Person.vb: Call the activate method on every field access

Implementing the IActivatable-interface manually for every class is repetitive and error prone. That's why this process can be automated. See "TA Enhanced Example"

The last step is to enable transparent persistence via configuration.

IEmbeddedConfiguration configuration = Db4oEmbedded.NewConfiguration();
configuration.Common.Add(new TransparentActivationSupport());
IObjectContainer container = Db4oEmbedded.OpenFile(configuration, DatabaseFileName);
TransparentActivationExamples.cs: Activate transparent activation
Dim configuration As IEmbeddedConfiguration = Db4oEmbedded.NewConfiguration()
configuration.Common.Add(New TransparentActivationSupport())
Dim container As IObjectContainer = Db4oEmbedded.OpenFile(configuration, DatabaseFileName)
TransparentActivationExamples.vb: Activate transparent activation

Now transparent persistence is enabled. Now you can navigate the object-graph as deep as you want. The transparent activation will load the objects from the database as you need them.

using (IObjectContainer container = OpenDatabaseTA())
{
    Person person = Person.PersonWithHistory();
    container.Store(person);
}
using (IObjectContainer container = OpenDatabaseTA())
{
    Person person = QueryByName(container, "Joanna the 10");
    Person beginOfDynasty = person.Mother;

    // With transparent activation enabled, you can navigate deeply
    // nested object graphs. db4o will ensure that the objects
    // are loaded from the database.
    while (null != beginOfDynasty.Mother)
    {
        beginOfDynasty = beginOfDynasty.Mother;
    }
    Console.WriteLine(beginOfDynasty.Name);

    // Updating a object doesn't requires no store call.
    // Just change the objects and the call commit.
    beginOfDynasty.Name = "New Name";
    container.Commit();
}
TransparentActivationExamples.cs: Transparent activation in action
Using container As IObjectContainer = OpenDatabaseTA()
    Dim joanna As Person = Person.PersonWithHistory()
    container.Store(joanna)
End Using
Using container As IObjectContainer = OpenDatabaseTA()
    Dim joanna As Person = QueryByName(container, "Joanna the 10")
    Dim beginOfDynasty As Person = joanna.Mother

    ' With transparent activation enabled, you can navigate deeply
    ' nested object graphs. db4o will ensure that the objects
    ' are loaded from the database.
    While beginOfDynasty.Mother IsNot Nothing
        beginOfDynasty = beginOfDynasty.Mother
    End While
    Console.WriteLine(beginOfDynasty.Name)

    ' Updating a object doesn't requires no store call.
    ' Just change the objects and the call commit.
    beginOfDynasty.Name = "New Name"
    container.Commit()
End Using
TransparentActivationExamples.vb: Transparent activation in action