New Architecture

The way I published the plugin architecture for Couchbase Lite .NET 1.2.0 was not the best.  Because of this I made a lot of effort to refactor things to make it less error-prone.  I am going to explain this architecture in this post.  First, a diagram:

         +-------------------------------------+
         |Couchbase Lite Bonjour Discovery     |
         |(Couchbase.Lite.Listener.Bonjour.dll)|
         +-----------------+-------------------+
                           |
                           |
            +--------------v---------------+
            |Couchbase Lite REST API       |          ^
            |(Couchbase.Lite.Listener.dll) |          +
            +--------------+---------------+      Optional
                           |                          +
    +-------------------------------------------------+
    +                      |
Required     +-------------v--------------+
    +        |Couchbase Core Functionality|
    v        |(Couchbase.Lite.dll)        |           ^
             +-------------+--------------+           +
                           |                       Public
                           |                          +
    +-------------------------------------------------+
    +                      |
Internal        +----------v----------+
    +           |Storage Engine Plugin|
    v           +----------+----------+
                           |
                           |
                  +--------v--------+
                  |Native Components|
                  +-----------------+

This is the overall structure of the library at the moment.  I’m going to talk a bit about the Storage Engine Plugin and Native Components section here.  Time for another diagram:

                                                        +----------------------------+
                                                        |Couchbase Core Functionality|
                                                        |(Couchbase.Lite.dll)        |
                    +-----------------------------------+                            +-----------------------------------+
                    |                                   |ICouchStore                 |                                   |
                    |                                   +-------------+--------------+                                   |
                    |                                                 |                                                  |
                    |                                                 |                                                  |
+-------------------v----------------------+     +--------------------v---------------------+     +----------------------v-------------------+
|System SQLite Storage Engine              |     |SQLCipher Storage Engine                  |     |ForestDB Storage Engine                   |
|(Couchbase.Lite.Storage.SystemSQLite.dll) |     |(Couchbase.Lite.Storage.SQLCipher.dll)    |     |(Couchbase.Lite.Storage.ForestDB.dll)     |
+-------------------+----------------------+     +--------------------+---------------------+     +----------------------+-------------------+
                    |                                                 |                                                  |
                    |                                                 |                                                  |
    +---------------v-----------------+               +---------------v-----------------+          +---------------------v------------------+
    |SqliteCouchStore : ICouchStore   |               |SqliteCouchStore : ICouchStore   |          |ForestDBCouchStore : ICouchStore        |
    |                                 |               |                                 |          |                                        |
    |sqlite3.dll (Windows)            |               |sqlcipher.dll (Windows)          |          |CBForestInterop.dll (Windows)           |
    |(Others not needed)              |               |libsqlcipher.dylib (OS X)        |          |libCBForestInterop.dylib (OS X)         |
    +---------------------------------+               |libsqlcipher.a (iOS)             |          |libCBForestInterop.a (iOS)              |
                                                      |libsqlcipher.so (Android / Linux)|          |libCBForestInterop.so (Android / Linux) |
                                                      +---------------------------------+          +----------------------------------------+

This is a diagram of just the storage engine plugin architecture. I’m going to explain it a bit now.  As of 1.2.0, Couchbase.Lite.dll cannot be run on its own anymore.  It requires at least one storage plugin.  This refactor comes as part of introducing ForestDB into the mobile product of Couchbase.  We want to provide the option to use it, while keeping the default functionality the same in case we run into unintended consequences.  There is also an option for using a specialized version of SQLite that encrypts data at the page level for data security.  Users are free to include any combination of the three, though the presence of SQLCipher will override System SQLite.  Let’s delve a bit into how this works:

ICouchStore is an interface that exists in Couchbase.Lite.dll and describes the things that a storage engine needs to do. Couchbase.Lite.dll only knows about this interface.  The concrete implementations of this interface exist in separate assemblies.  These are what are referred to as the Storage Engine plugins.  They contain an implementation of ICouchStore as well as any native libraries that are needed.  On iOS, you won’t see the native library directly since it will be statically linked and on Android all the libraries are embedded into the managed DLL and chosen at build time.

The advantage of this is that since the entire managed implementation is separated into another assembly, we can quickly determine whether or not the implementation is available by attempting to instantiate it via Activator.CreateInstance. This is better than the previous way of simply swapping out native libraries and checking for things such as DllNotFoundException and EntryPointNotFoundException.

So, as a consumer of Couchbase Lite, if you want to install these plugins you simply need to include the relevant Nuget package.  For example, if you want ForestDB support you can install the Couchbase.Lite.Storage.ForestDB package.  This package includes a managed DLL with the ForestDB implementation of ICouchStore, the native ForestDB library files, and a file that tells the Visual C# project which native library to include, if applicable.

Leave a comment