Correspondence in NuGet

I have released Correspondence for Windows Phone 7 to NuGet. Correspondence is a NoSQL database for the phone and other occasionally connected clients. While offline, it queues all of your user’s changes. While online, it pushes those changes to a synchronization server, which in turn pushes it to other devices.Create a Windows Phone 7 application and install the following package:

Correspondence.WindowsPhone.AllInOne

This will add models, view models, a view model locator, and a synchronization service to your application.

Models

Correspondence models are expressed in a language called Factual. The package adds a folder called Models that contains a Factual file and a T4 template to parse it. The first thing you’ll want to do after adding the package reference is to hit the “Transform All Templates” button to generate some code.The starter model contains concepts useful for any Windows Phone 7 application. First it has an Identity:

fact Identity {
key:
   string anonymousId;
   ...
}

The Identity fact is uniquely identified by the user’s anonymous Windows Live ID. If they move to a different device, they carry their Identity with them. This makes it really easy to collaborate between users.The model also has the ability to disable and reenable toast notifications:

fact DisableToastNotification {
key:
   unique;
   Identity identity;
query:
   bool isReenabled {
       exists EnableToastNotification e : e.disable = this
   }
}

fact EnableToastNotification {
key:
   DisableToastNotification* disable;
}

The Identity fact queries to see if there are any DisableToastNotification facts:

fact Identity {
   ...
query:
   DisableToastNotification* isToastNotificationDisabled {
       DisableToastNotification d : d.identity = this
           where not d.isReenabled
   }
}

The Identity partial class adds a property that turns these successor facts into a simple boolean property:

public partial class Identity
{
    public bool ToastNotificationEnabled
    {
        get { return !IsToastNotificationDisabled.Any(); }
        set
        {
            if (IsToastNotificationDisabled.Any() && value)
            {
                Community.AddFact(new EnableToastNotification(IsToastNotificationDisabled));
            }
            else if (!IsToastNotificationDisabled.Any() && !value)
            {
                Community.AddFact(new DisableToastNotification(this));
            }
        }
    }
}

Extend these facts and build your model in model.fact. Hit “Transform All Templates” after each change to regenerate the classes. Create partial classes to add your own business logic. ViewModelsThe package also adds a ViewModels folder, which contains two view models:

  • MainViewModel
  • SettingsViewModel

The main view model is just an empty starting place. Add properties to this view model to data bind to controls on your main page.Settings view model has one property started for you. It exposes the ToastNotificationEnabled property in the Identity. This is just a simple pass-through. You don’t raise PropertyChanged events or inherit a base class. Correspondence will raise the PropertyChanged event for you. This works because Correspondence is built on Update Controls.

public bool ToastNotificationEnabled
{
    get { return _identity.ToastNotificationEnabled; }
    set { _identity.ToastNotificationEnabled = value; }
}

The ViewModels folder also contains a ViewModelLocator class. Open the Readme.txt file for instructions on adding this class to your application resources, and referencing it in your views. As you create your own view models, follow the pattern demonstrated with these two existing view models to add them to the locator.

public class ViewModelLocator
{
    private readonly MainViewModel _main;
    public ViewModelLocator()
    {
        ...
        _main = new MainViewModel(_synchronizationService.Identity);
        ...
    }
    public object Main
    {
        get { return ForView.Wrap(_main); }
    }
}

SynchronizationService

Correspondence would be just another isolated-storage-based NoSQL database if it weren’t for the synchronization service. For the most part, this class will be invisible to you. It is initialized in the view model locator, and it works automatically.Every time you store a published fact, the synchronization service wakes up and pushes it to the server. If the device is off-line at the time, the fact is queued. The synchronization service will wake up when the network becomes available and start pushing facts.

When another device publishes a fact to which you have subscribed, the server will send a push notification. The synchronization service responds to these push notifications and adds the facts to the repository. Your app is notified via data binding, and the UI updates.The synchronization service is also watching the ToastNotificationEnabled property. When it is true, it subscribes for toast notifications. When it is false, it unsubscribes.

There are two parts of the synchronization service that you are likely to change. The first is the POXConfigurationProvider. When you create an account with a synchronization server, you will be issued a URL, a user name, and a password. Put these into this class.

public POXConfiguration Configuration
{
    get
    {
        string address = "https://historicalmodeling.com/correspondence_server_web/pox";
        string userName = "<<Your username>>";
        string password = "<<Your password>>";
        return new POXConfiguration(address, "MyCoolWindowsPhoneApplication", userName, password);
    }
}

The second is the subscriptions. The synchronization service subscribes to the Identity. The device will receive any facts published to the user’s Identity. As you develop your own model, you will create other publications. Add linq expressions here to subscribe to those facts.

_community = new Community(IsolatedStorageStorageStrategy.Load())
    .AddAsynchronousCommunicationStrategy(new POXAsynchronousCommunicationStrategy(configurationProvider))
    .Register<CorrespondenceModel>()
    .Subscribe(() => _identity)
    ;

More to come

There is definitely a learning curve for historical modeling in general, and Correspondence in particular. Please review the body of articles here and on Historical Modeling. I will also be posting videos and examples over the next few weeks.I am also opening my synchronization server for a private beta. Please email or mention me to reserve your place. mperry@mallardsoft.com or @michaellperry.

Leave a Reply

You must be logged in to post a comment.