Portable Usage Scenario of Lex.DB

Preface

One of the beauties of .NET framework is that it works the same way across all Microsoft platforms including PCs, tablets, gaming consoles, phones and browsers. However there are still some major differences between CLR and BCL versions to make the same code truly cross-platform.

For example, WinRT platform (Windows Store Apps) lacks FileStream class and, to accommodate COM reflection, turns CLR reflection along with messed up namespaces upside down. Windows Phone 7 BCL lacks HashSet and several Linq.Expression classes. Silverlight 5 lacks slim versions of synchronization primitives like ReaderWriterLockSlim, Stopwatch and BufferedStream classes.

It is not always that lacking features are just missing. It could be that the certain version of platform offers some other ways of doing the same things. Theoretically, if we stay in subset of .NET which is common between all these platforms, we could produce truly cross-platform assembly. We just need to use only those methods and classes which are available across all target platforms we’d like to address.

This technique is already available (built-in in VS2012) and called Portable Class Library. By selecting different combinations of target platforms (.NET 4.0-4.5, SL 4-5, WP 7-7.5-8, .NET for Windows Store Apps, Xbox 360) we limit our API set to lowest common denominator of those target platforms. The produced assembly is compatible with all target platforms on binary level, so no recompilation required.

Isn’t this a dream?

But practical experience proves that portable API set is too limited to be useful. The more-or-less complex library like Lex.DB is just impossible to make 100% portable across all target platforms: no files to read/write data, no thread synchronization and no expressions to make Lex.DB fast. Consider all issues and there is no Lex.DB.

What about abstracting some platform-dependent parts from Lex.DB into interfaces and implementing them in platform-specific assemblies? Nice idea, but what will we end up with? We’ll get a portable assembly that requires platform-dependent sidekick anyway. Right now we have just one platform-dependent all-in-one assembly, so why bother?

Wait; there should be some way to make portable database access. Yes, there is. Abstracting data access logic of your app itself.

Portable Way

The idea is simple. We put everything what could be portable in our portable Common Logic assembly. Some components have to interact with platform specific code. To make them portable with need to break the dependency by abstracting interaction via “service” interface.

  • Data Entities – data classes to read/write in Lex.DB
  • View Models – non-visual models of UI in your app
  • Business Logic to work with data entities and view models
  • Resources – text localization and other
  • Interfaces to abstract underlying platform features (IMessageBox, IDialog, IApplication)
  • IDataAccessService interface to abstract data access
  • Service Locator or IoC (Inversion-Of-Control) singleton to obtain platform-specific service implementations

Platform-specific application references platform-specific Lex.DB and portable Common Logic assembly, gaining access to all classes above. During initialization phase our application sets the Service Locator or IoC-container up with platform-specific implementations of these services to allow Common Logic interact with the platform.

portable

Working example

I wrote an article to Nokia Developer wiki, in details explaining this technique. The example provided is a Contacts application, that works on all MS platforms: WinRT, Windows Phone 8, Silverlight 5, .NET (WPF). 10000 records are loaded in a split second. Check it out.

In the example I use my Visual Studio plugin KindOfMagic, which makes implementation of INotifyPropertyChanged objects completely effortless. This plugin saved me lot of nerves and time. Check it also out.

 

That’s it for today.

10 thoughts on “Portable Usage Scenario of Lex.DB”

  1. Using now the lexDb to store image cache, works great. Would it be possible to add function to get the total data size? The reason is that I’m using the database as a cache and want to set the cache to a maximum size. If cache increases above maximum size, then I will delete the oldest records. Looks like the data is held in one datafile, would be nice to get this datafile size throught functions in the lexDb interface

  2. Looks reasonable. For SL, for instance, there is a size quota for isolated storage as well.

    I’ll put it in the next minor release.

    Thank you for the feedback!

  3. Lex,

    What is the trick to the get contactsShared package to compile? I’m running into issues with the KindOfMagic…

    1>D:\Development\Samples\Lex.ContactsApp\ContactsApp\packages\KindOfMagic.1.2.1\tools\KindOfMagic.targets(5,5): error MSB4018: The “MagicTask” task failed unexpectedly.
    1>D:\Development\Samples\Lex.ContactsApp\ContactsApp\packages\KindOfMagic.1.2.1\tools\KindOfMagic.targets(5,5): error MSB4018: System.TypeLoadException: Could not load type ‘Mono.Cecil.GlobalAssemblyResolver’ from assembly ‘Mono.Cecil, Version=0.9.5.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756′.
    1>D:\Development\Samples\Lex.ContactsApp\ContactsApp\packages\KindOfMagic.1.2.1\tools\KindOfMagic.targets(5,5): error MSB4018: at KindOfMagic.MagicTask.Execute()
    1>D:\Development\Samples\Lex.ContactsApp\ContactsApp\packages\KindOfMagic.1.2.1\tools\KindOfMagic.targets(5,5): error MSB4018: at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
    1>D:\Development\Samples\Lex.ContactsApp\ContactsApp\packages\KindOfMagic.1.2.1\tools\KindOfMagic.targets(5,5): error MSB4018: at Microsoft.Build.BackEnd.TaskBuilder.d__20.MoveNext()

    thx

  4. Lex,

    What is the trick to the get ContactsShared project to load? I’m running into issues with the KindOfMagic…

    E:\Work – VS.NET 2012\Databases\Lex.DB\Portable Usage\ContactsApp\ContactsShared\ContactsShared.csproj : error : The imported project “C:\KindOfMagic.targets” was not found. Confirm that the path in the declaration is correct, and that the file exists on disk. E:\Work – VS.NET 2012\Databases\Lex.DB\Portable Usage\ContactsApp\ContactsShared\ContactsShared.csproj

    Do I need to actually install KindOfMagic?

    1. KindOfMagic automates INotifyPropertyChanged implementation during compile time. After installing KoM you may start VS as Administrator to enable KoM to initialize OS KINDOFMAGIC environment variable for MSBuild.

      You may as well implement INotifyPropertyChanged differently. In this case just remove KindOfMagic import from *.csproj. It looks like this:

      <Import Project=”$(KINDOFMAGIC)\KindOfMagic.targets” />

  5. I am very impressed with Lexdb. How is the portable class library coming along? I noticed simple injector is available on iOS, Android and WP8.

Leave a Reply

Connect with:

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>