One of the big themes of PDC this year was Windows Azure and Microsoft’s cloud computing initiative. Live Services is one of the building blocks of Windows Azure, and includes a set of services known as Live Mesh. I did a blog post about Live Mesh back in April when it was first announced. With lots of enthusiasm I speculated about how this would enable us to build offline/desktop enabled Silverlight applications. During the second day keynote Scott Guthrie, coding hero and vice president at Microsoft, announced that;
Photo by DBegley - check out original on Flickr
This announcement immediately caused a lot of buzz in the Twitter-sphere. What made the announcement even more interesting is that a lot of people didn’t quite get what Scott was talking about, or if they even showed Silverlight running outside the browser at all. So what was the Silverlight out-of-browser story at PDC? After Scotts keynote Anthony Rose entered stage and demoed their BBC iPlayer. He didn’t explicitly say that this was the “Silverlight running on the desktop”-story, but what he was showing was the iPlayer implemented as a Mesh-Enabled Silverlight application running on the desktop!
Photo by DBegley - check out the original on Flickr
In this blog post I’m going to show how I Mesh-enabled the Dive Log application using the Live Framework. I will also try to cover some of the benefits of using Live Mesh as an application platform for web application.
To build Mesh-Enabled Web Applications you need access to the Live Framework SDK and Tools. The SDK is currently only available in a private CTP, and to get access you need to apply for a token through the Microsoft Connect site. I don’t know how many people they will let in on the CTP, or how long the process of getting a token takes.
Once you have downloaded and installed the SDK you get a new project type called Live Framework, which comes in two flavors; “Mesh-enabled Web Application” and “Silverlight Mesh-enabled Web Application”. The difference is that the first one is for writing JavaScript and HTML based Mesh-applications, while the second is for Silverlight applications that use the Live Framework libraries.
After selecting the “Silverlight Mesh-enabled Web Application” template you get a new solution with two projects; a Silverlight 2 project and a Live Framework project. The Live Framework project has a reference to the Silverlight project, and contains a simple HTML and JavaScript file to embed the Silverlight application on the HTML page. The project also contains an icon for the application, and an XML manifest file describing the application. The Silverlight project has references to two new assemblies; Microsoft.LiveFX.Client and Microsoft.LiveFX.ResourceModel. These are the Live Framework libraries that give you a managed API for Live Services. All Live Services are based on open protocols and standards like HTTP, ATOM, FeedSync and RSS, so you could write applications without these libraries, in any language or platform you like, but Live Framework makes it allot easier by providing a nice abstraction layer on top of the web services.
The first thing I did after creating a new Live Framework project was to remove the automatically generated Silverlight 2 project. Instead I included my existing Dive Log Silverlight project and referenced the Live Framework Silverlight assemblies.
The Dive Log application was originally written as a demo for my TechEd talks back in September. One of the things I wanted to demonstrate was how to use the Model-View-ViewModel pattern in a Silverlight application, and how this can make your application easier to design in Expression Blend. The way I did that is to use dependency injection to inject a mock-implementation of any external dependencies, like web service proxies, into the view model. That way the mock service can generate sample data when the code is being consumed in Expression Blend. When the application is running in the browser the real web service will be used.
The benefit of this design is that I can easily configure my inversion of control container to use different implementations of different application services. So to first run the Dive Log application inside Live Mesh I simply configured the IoC container to always use the mock implementation of the web service. That way I could deploy my application to Live Mesh without having to prepare my web services for cross domain access.
After TechEd I have extended the Dive Log application with new features like printing support and support for back- and forward navigation in the browser. These features depend on the ASP.NET AJAX client library to be available on the page hosting the application. For my Mesh-enabled Dive Log I can’t depend on these libraries to be present, and I guess they don’t make sense when the application is deployed on the desktop anyway. So to disable these features I simply made an empty implementation of the IPrintDives and IManageHistory interfaces and configured my IoC container to use these to handle browser history and printing.
Once the application was configured to use the mock web service, and to disable printing and history, I could simply hit F5 to build and deploy the application to Live Mesh. The Live Framework project template includes a build task that will connect and deploy the application to Live Mesh. Currently there is no local development environment for Mesh-enabled web applications, something that can be a little bit bothersome as you have to redeploy the application to Live Mesh every time you make a change.
The next step of Mesh-enabling the Dive Log application is to use the Live Framework Resource Model as the data storage for logged dives. The original application uses a web service to store dives remotely. This diagram shows a high level overview of the Live Framework Resource model. The blue boxes indicate the main components the Dive Log application will use.
As I mentioned earlier the web service is an external dependency that is injected into the View Model using an IoC container. A trick I’ve used on many projects is to extract an interface defining the methods and events used on the web service client class. I then use a partial class to implement this interface on the automatically generated web service client class. This enables me to implement multiple versions of the interface, for instance for design time data or unit testing. This design enables me implement a new service that reads and writes dives to the Live Framework Resource Model. A simple configuration change of the IoC container will inject the Live Framework based service to the View Model. That way I don’t have to change any code in the UI or the View Model to use Live Mesh as my data storage.
The next challenge I faced was figuring out how to map my Dive Log application against the different concepts of the Live Framework Resource Model. After reading about the resource model my initial idea was to create one Mesh Object for each Dive Log, and then start adding items to a Data Feed. When I tried to create a new Mesh Object from my Silverlight application I got some weird exceptions. After discussion this on the Live Framework forum I learned that Mesh-enabled web applications don’t have permission to create new Mesh Objects. After some more trail-and-error, as well as watching sessions Live Framework sessions from PDC I came up with the following mapping of Dive Log concepts against the Live Framework Resource Model:
The Mesh Object is the level of granularity for sharing, synchronization and authorization. In fact each instance of a Mesh-enabled web application is in itself a Mesh Object. This means that each Mesh-enabled web application got access to a single Mesh Object; the object representing the application instance. This enables you to share application instances with other users, and the Live Framework Client will synchronize the Mesh Object (application instance) across your devices. If you want to create two dive logs, one for hobby dives and one for professional dives, you simply create two application instances. This would create two Mesh Objects, one for each instance, which you could shared with other users and synchronize across devices. The following diagram illustrates the application sharing model. Each instance is a Mesh Object shared with another user, and both the application and its data get synchronized between users.
After working out how to map the Dive Log against the Live Framework Resource Model the next step was to write the actual implementation of the storage service. This was fairly straight forward as the Live Framework provides a nice API to work with the Live Services. In fact the complete implementation of the Live Framework backed storage service was less than 200 lines of code. One of the changes I had to make to my Dive-object was to add a new Mesh ID so that I could map Dive-objects against Sync Entry objects. When the user clicks the save button the code will create a new Sync Entry object and set the Dive-object as the user data. This enables you to serialize custom objects into a Mesh Sync/Data Entry. Both Sync- and Data Entries hang of a Data Feed. The main difference is that Sync Entries is the implementation of the Feed Sync standard. This helps you deal with synchronization of data across devices. This is helpful since multiple users could be writing data to the same application instance, some who might be offline and only synchronize data back into the cloud at a later stage.
The following piece of code shows the implementation of the save method. The code will iterate over each dive being saved and check if it has been changed. If the object is changed the code will see if it can find a Sync Entry matching the Dive. If it finds a Sync Entry it will update the object by calling SetUserData. If no Sync Entry can be found a new one is created and the dive object is stored by calling SetUserData on the new Sync Entry. Finally the Synchronize method is called on the Data Feed. This will push any changes made locally back into the cloud, as well as read any new objects added remotely by other users/devices.
Mesh-enabled web applications are a new type of applications. They are developed using web techniques like HTML, CSS, JavaScript or Silverlight, but can be deployed to the Live Mesh, and executed both inside the browser and on the desktop. This new application model opens up several new scenarios, and I think the Dive Log is a good example of an application that can benefit from being Mesh-enabled.
These are just some of the benefits from Mesh-enabling the Dive Log application. I think Live Mesh and Live Services are going to be an interesting application platform to watch as it matures. Currently the benefits for consumer based applications are obvious. It will be interesting to see if this platform can provide value for more business focused applications.
I have uploaded the source code of the Mesh-enabled Dive Log application. It is a simple Silverlight 2 application without the Live Framework project. You need to download and install the Live Framework SDK separately and then create a new Mesh-enabled Silverlight Project. Follow the steps described earlier in this post and add the Dive Log Silverlight application to your Live Framework project.
I have also published the Dive Log application to Live Mesh if you just want to run it as an end-user. You need to use the Live Mesh Tech Preview online environment, as well as download the Live Mesh Tech Preview client (if you want to run the application from your desktop and not only inside the browser).
Remember Me
a@href@title, strike
Page rendered at Thursday, September 02, 2010 9:55:05 PM (W. Europe Daylight Time, UTC+02:00)
Powered by newtelligence dasBlog 2.3.9074.18820
© Copyright 2010, Jonas Follesø
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
This blog theme is inspired by a theme original designed and copyrighted 2007, by Alexander Groß and is used with his explicit permission.