Durch Christian's Blogeintrag bin ich auf Microsoft Live Labs Volta aufmerksam geworden. Mit Volta soll es möglich sein Web Anwendungen Technologie-unabhängig zu entwickeln. Unabhängig von der eigentlichen Skript Implementierung, die man für verschiedene Browser berücksichtigen muss. Unabhängig dahingehend, dass man dynamisch entscheiden kann, ob alles in einem Prozess gehostet wird oder mehrere Tiers zur Verfügung stehen, man braucht sich nicht mal Gedanken über die Kommunikationsprotokolle zu machen. Man definiert lediglich Verhalten.

Wie macht Volta das? Volta ist in erster Linie ein Recompiler. Man programmiert ganz normal in seiner .NET Sprache der Wahl (momentan wird C# am besten unterstützt) und Volta rekompiliert dann die Anwendung auf die gewünschte Zielplatform. Hierbei setzt Volta nur auf das IL auf, also nicht auf den eigentlichen Source. In dem folgenden kleinen Beispiel wird die Anwendung dementsprechend auf JavaScript rekompiliert und im Browser lauffähig.

Die Installation integriert Volta in Visual Studio 2008 und stellt somit ein paar Projekttemplates zum Einstieg zur Verfügung. Mit dem Windows Forms Template konnte ich allerdings noch nichts anfangen, vielleicht hat ja jemand ein Beispiel dafür?

shot1

Die Solution für das kleine Beispielprojekt ist hier zu sehen und es wird eine VoltaPage angelegt. Ich konnte allerdings später kein dediziertes Page-Item Template finden, insofern einfach Klasse erschaffen und von Page ableiten.

shot2

VoltaPage1.cs ist die Klasse mit der Implementierung der Funktionalität. Das Design selbst findet sich in der entsprechenden Page.html Datei wieder. In Page.html werden einfach nur die Elemente definiert mit denen man später programmieren möchte.

   1: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   2:   "http://www.w3.org/TR/html4/loose.dtd">
   3: <html>
   4: <head>
   5:     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
   6:     <title>VoltaTest</title>
   7:     <link rel="shortcut icon" href="/favicon.ico"/>
   8:     <style type="text/css">
   9:     </style>
  10: </head>
  11: <body>
  12:     <input id="Button1" type="button" value="Zeige Ergebnis" />
  13:     <button id="async">
  14:         Async aufrufen!
  15:     </button>
  16:     <div id="output">
  17:     </div>
  18: </body>
  19: </html>

Die drei Elemente Input, Button und Div benutze ich in der VoltaPage1 Klasse. Zusätzlich wird dort noch ein Volta Custom Control VoltaControl1 mit geladen und dem Div Element hinzugefügt.

   1: using System;
   2: using Microsoft.LiveLabs.Volta.Html;
   3:  
   4: namespace VoltaTest
   5: {
   6:     public partial class VoltaPage1 : Page
   7:     {
   8:         Input submit;
   9:         Button async;
  10:         Div output;
  11:         Person person;
  12:  
  13:         VoltaControl1.VoltaControl1 myControl;
  14:  
  15:         public VoltaPage1()
  16:         {
  17:             InitializeComponent();    
  18:             submit.Click += new HtmlEventHandler( btn_Click );
  19:             async.Click += new HtmlEventHandler( async_Click );
  20:         }
  21:  
  22:         partial void InitializeComponent()
  23:         {
  24:             submit = Document.GetById<Input>( "Button1" );
  25:             async = Document.GetById<Button>( "async" );
  26:             output = Document.GetById<Div>( "output" );
  27:             person = new Person();
  28:             myControl = new VoltaControl1.VoltaControl1();
  29:             output.AppendChild( myControl );
  30:         }
  31:  
  32:         void async_Click()
  33:         {
  34:             person.SayHelloWorld( msg =>
  35:             {
  36:                 output.InnerText = "async: " + msg;
  37:             } );
  38:         }
  39:  
  40:         void btn_Click()
  41:         {
  42:             output.InnerText = person.SayHelloWorld();
  43:             MyLibrary.SayHelloToPerson( "Dariusz" );
  44:         }
  45:     }
  46: }

Zeile 8-10 definiert die entsprechenden HTML Elemente. Zeile 11 ist die Klasse Person die im Projekt enthalten ist. Zeiler 13 ist das Volta Custom Control VoltaControl1. Das Custom Control selbst ist wiederum eine Klasse mit einem entsprechenden HTML Design in einem eigenen Assembly. Volta Controls sind Composite Controls. Wichtig ist das man in der Partial Method InitializeComponent() die jeweiligen HTML Elemente mittels des UI Objektmodells zuweist, so das man im späteren Verlauf auch damit arbeiten kann. Dies geschieht in Zeile 24 - 26. In Zeile 28-29 sieht man die Integration des Volta Custom Control welches einfach per AppendChild an ein HTML Element hinzugefügt wird.

Die Klasse Person besitzt weitere Volta-Spezifische Attribute. Zum einen eine Anweisung in einem Multi-Tier Szenario beim ersten Prozess zu bleiben RunAtOrigin, zum anderen das die Methode SayHelloWorld asynchron aufgerufen werden soll über Async.

   1: using System;
   2: using Microsoft.LiveLabs.Volta.MultiTier;
   3:  
   4: namespace VoltaTest
   5: {
   6:     [RunAtOrigin]
   7:     public class Person
   8:     {
   9:         [Async]
  10:         public extern void SayHelloWorld( Callback<string> callback );
  11:  
  12:         public string SayHelloWorld()
  13:         {
  14:             return "Hello, world.";
  15:         }
  16:     }
  17: }

Des wegen ist in Zeile 34-38 der Aufruf über einen delegate realisiert. In Zeile 43 wird zudem eine JavaScript Methode aufgerufen. Diese Methode ist in diesem Beispiel einfach intern über das Import Attribute deklariert.

   1: using System;
   2: using Microsoft.LiveLabs.Volta;
   3:  
   4: namespace VoltaTest
   5: {
   6:     public class MyLibrary
   7:     {
   8:         [Import( "function helloPerson( personName ) { alert( 'Hello, ' + personName ); }" )]
   9:         public static extern void SayHelloToPerson( string personName );
  10:     }
  11: }

Volta stellt also Interop Mechanismen von .NET => JavaScript und von JavaScript => .NET zur Verfügung. Genauso wie man Skripte importieren kann, lassen sich Funktionen auch nach JavaScript mittels des Export Attributes exportieren und in JavaScript nutzen.

In Volta kommt bereits eine Bibliothek für Virtual Earth mit, welches das JavaScript Model in .NET Klassen umsetzt und zur Verfügung stellt. Natürlich dynamisch.

Volta ist für mich ein weiterer faszinierender Ansatz, Technologie zu abstrahieren. Man darf gespannt sein, in welche Richtung sich das ganze entwickeln wird.