Archiv für Oktober 2008

WF Essentials – Persistenz von Workflows – Teil 1

Mittwoch, 29. Oktober 2008

Dies ist der erste Teil eines mehrteiligen Artikels zu den Persistenz Mechanismen in der Windows Workflow Foundation.
Zu Beginn werden mal die Workflow Persistenz Grundlagen beleuchtet. Später geht’s dann um den Einsatz des Persistenz Services in Workflow Services und in einer Server Farm.

Die Windows Workflow Foundation stellt für die Persistenz von Workflow Instanzen den Core Dienst SqlWorkflowPersistenceService zur Verfügung. Dieser benötigt einen SQL Server, andere Datenbanken werden nicht unterstützt. Es ist allerdings möglich, einen eigenen Persistenz Dienst zu schreiben, dazu aber später mehr.

Wenn die WorkflowRuntime so konfiguriert wird, dass sie den SqlWorkflowPersistenceService verwenden soll, wird der aktuelle Status der Workflow Instanzen, welche sich gerade im Wartezustand befinden, in der Datenbank persistiert.

Wann genau wird nun eine Workflow Instanz persisitiert?

Die Persistierung kann nebst dem Umstand, dass die Workflow Instanzen einen Neustart des Workflow Hosts überleben, die Skalierbarkeit einer einzelnen WorkflowRuntime erhöhen, da nicht benötigte Workflow Instanzen aus dem Speicher entfernt werden.

Der SqlWorkflowPersistenceService kann via Applikations Konfigurationsfile oder via Code eingesetzt werden.

Im Konfigurationsfile

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

    <configSections>
        <section name="WorkflowRuntimeConfiguration"
                 type="System.Workflow.Runtime.Configuration.WorkflowRuntimeSection, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    </configSections>

    <WorkflowRuntimeConfiguration>
        <CommonParameters>
            <add name="ConnectionString"
                 value="Data Source=localhost;Initial Catalog=WFStore;User=wf;Password=wf;" />
        </CommonParameters>

        <Services>
            <add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                 UnloadOnIdle="true" />
        </Services>

    </WorkflowRuntimeConfiguration>

</configuration>

Im Code

// Adjust the connection string according to your environment.
var connectionString = "Data Source=localhost;Initial Catalog=WFStore;User=wf;Password=wf;";

// When true, the service will persist idle workflows. The service default value is false.
bool unloadOnIdle = true;

// Specifies for how long the service will lock the instance record in the database.
// The service default value is TimeSpan.MaxValue.
TimeSpan instanceOwnershipDuration = new TimeSpan(0, 2, 0);

// The service will check for expired timers in the database this often.
// The service default value is 2 minutes
TimeSpan loadingInterval = new TimeSpan(0, 0, 5);           

var persistenceService = new SqlWorkflowPersistenceService(connectionString,
                                                           unloadOnIdle,
                                                           instanceOwnershipDuration,
                                                           loadingInterval);
workflowRuntime.AddService(persistenceService);

Das angehängte Beispiel Projekt für Visual Studio 2008 zeigt diese beiden Varianten. Sie benötigen zusätzlich zum Beispielprojekt eine SQL Server Datenbank. Eine SQL Server Express Installation auf dem Entwicklungsrechner reicht dabei völlig aus.

Die SQL Skripte für das Anlegen des DB Schemas und der benötigten Stored Procedures findet man unter

C:\Windows\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\EN

Beispiel Projekt: WorkflowPersistence.zip

Amazon Kindle kommt nach Europa

Montag, 13. Oktober 2008

In der heutigen Ausgabe der Sonntagszeitung wurde der Amazon Kindle im Multimediateil anlässlich der nächste Woche in Frankfurt stattfindenden Buchmesse besprochen.
Auch das Schweizer Fernsehen hat letzte Woche in der Sendung Kulturplatz einen Beitrag über das Gerät gebracht.
Noch ist das digitale Lesegerät hierzulande nicht verfügbar, doch bereits jetzt polarisiert der E-Book Reader.

Wenn ich die Kommentare im besagten Artikel durchlese, kommt mir die Situation etwa so vor, wie ca. 1998, als der Boom um Musik im MP3 Format so richtig losging, und die Plattenfirmen das ganze zuerst mal ignoriert haben. Als dann realisiert wurde, was das ganze auf sich hat, hat man die Technologie nur als Bedrohung wahrgenommen, und es wurde zuerst mal in alle Richtungen geklagt. Natürlich zieht der Vergleich nicht so ganz, schliesslich vertreibt Amazon keine illegalen Inhalte. Dass die Verlage und sogar auch Autoren die Technologie als Bedrohung und nicht als Chance für einen weiteren Vertriebskanal wahrnehmen, läuft jedoch genau nach dem selben Muster ab. Vielleicht muss ja zuerst wieder Apple ein solches Gerät auf den Markt bringen.

Als technikinteressierter Mensch und Vielleser verfolge ich die Entwicklung dieser Geräte seit vielen Monaten. Ausserdem bin ich seit etwa 6 Monaten stolzer Besitzer eines Sony Readers (PRS-505), den mir ein Freund aus den Staaten mitgebracht hat. Im Gegensatz zum Kindle kann man beim Sony Reader und auch beim Konkurrenzprodukt, dem Iliad von iRex, einer Phillips Tochter, auch ganz einfach eigene (PDF) Dokumente auf die Geräte kopieren. Beim Kindle geht dies zwar grundsätzlich auch, jedoch muss das entsprechendes Dokument dazu immer kostenpflichtig via Amazons Whispernet aufs Gerät geladen werden.

Obwohl der Reader für mich genau das richtige Gerät ist, werden es aus meiner Sicht die Geräte dieser Generation leider noch nicht schaffen, einen wirklichen Markt zu schaffen.

  • Sie sind zu teuer. Der Kindle kostet in den Staaten 360 US$, hier wird er wahrscheinlich noch teurer. Der alte Sony PRS-505 war in den USA etwas billiger, der neue PRS-700BC kostet 400US$. Der Iliad kostet noch mehr, nämlich ca. 500 €.
  • Sie sind zu langsam. Das Blättern einer Seite dauert einfach noch zu lange. Dies ist auch beim Sony Reader so.
  • Die Displays sind monochrom. Das stört beim Lesen eines Krimis oder Fachbuchs nicht weiter, beim Blättern in einer digitalen Zeitschrift jedoch schon.

Die Vorteile sollen aber auch erwähnt werden:

  • Die E-Paper Displays sind mit nichts zu vergleichen, was man bis jetzt am Bildschirm gelesen hat. Das Lesegefühl kommt Papier schon recht nahe. Auch stundenlanges Lesen ermüdet die Augen nicht mehr, als es auch beim Papier der Fall wäre.
  • Durch die neue Technologie wird extrem wenig Strom für die Darstellung resp. das Blättern der Seiten benötigt. Eine Akkuladung hält so sehr lange.
  • Durch die geringen Preise von grossen Speichermedien (SD Card, Memory Stick) kann man wirklich sehr viele Bücher für wenig Geld mit sich herumtragen.
  • Jeder Reader hat ein eigenes Dokumentenformat, kann aber auch PDFs anzeigen. Von vielen amerikanischen IT Fachverlagen kann man die Bücher mittlerweile auch als PDF kaufen. Beispiele und Vorreiter sind da APress und Manning.

Microsoft kündigt erste .NET 4.0 Features an

Mittwoch, 8. Oktober 2008

Während der Rest der (Finanz) Welt langsam zu Grunde geht, gibt Microsoft weiter Vollgas.
Normalerweise beschäftige ich mich erst im Detail mit Entwicklungstools und Technologien, wenn sie verfügbar sind. Betas, CTPs, Release Candidates und wie diese Versionen alle heissen, installiere ich schon lange nicht mehr. Die Zeit reicht einfach nicht mehr, in Projekten muss in der Regel das getan werden, was der Amerikaner lapidar “get the job done” nennt.
Ausserdem muss der interessierte .NET Entwickler erst mal die neuen Technologien des .NET 3.5 SP1 verdauen. Dies alles schliesst aber natürlich nicht aus, dass man sich über neue Technologien informiert.

So hat die am 1. Oktober von Microsoft veröffentlichte Meldung “Overview of WF 4.0, WCF 4.0, and Windows Server “Dublin” mein Interesse geweckt:

…Microsoft is enhancing both the .NET Framework and Windows Server. The company is adding significant functionality to the new version of Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) as part of the .NET Framework 4.0 release, including new messaging and REST capabilities in WCF, new workflow models, seamless integration between WF and WCF to support stateful and conversational services, and a new visual designer. The company is also introducing a set of enhanced Windows Server capabilities codenamed “Dublin” that will offer greater scalability and easier manageability, while extending Internet Information Services (IIS) to provide a standard host for applications that use workflow or communications.

Im Dokument, welches als Download zur Verfügung steht, fällt mir vor allem die Erwähnung der Dublin genannten Windows Server Technologie auf, welche den IIS erweitern wird. Ein Standard Host für WCF und WF Applikationen wäre eine feine Sache.
Natürlich kann man bereits jetzt mit überschaubarem Aufwand in IIS 6 + 7 die Workflow Services als zustandsorientierte, “durable” Dienste anbieten. Funktionen zur Versionierung, Überwachung und Monitoring und zum Deployment von Workflows oder WCF Diensten müssen jedoch noch selber implementiert werden.
Mit Dublin könnte sich der IIS langsam zum Ernst zu nehmenden Applikationsserver mausern. Dies werde ich mal im Auge behalten, mein persönliches Technologie Backlog wird also noch länger…

An der PDC2008, die Ende dieses Monats in Los Angeles stattfindet, wird eine CTP Version der drei Technologien abgegeben. Vielleicht mache ich ja da wieder einmal eine Ausnahme und installiere sie.

Ich bin ebenfalls gespannt, ob die für WF 4.0 angekündigten Erweiterungen die Workfow Foundation von einem reinen Toolset für Entwickler zu einer Technologie wandeln wird, die sich vermehrt in Produkten für Endanwender wieder findet.

Aktivierung von XOML Workflow Services

Dienstag, 7. Oktober 2008

Vor der Einführung der Workflow Services mit .NET 3.5 war das Leben eines .NET WF Entwicklers etwas einfacher. Man erzeugt einfach irgendwann eine (oder entgegen der weit verbreiteten Annahme auch mehrere) WorkflowRuntime, welche dann verschiedene Overloads der CreateWorkflow() Methode zur Verfügung stellten und so die Workflow Instanzen erzeugen können.

XOML Workflow Aktivierung mit der WorkflowRuntime

Je nachdem, ob die Workflow Definitionen in einem Assembly oder in XOML vorhanden sind, wählt man den entsprechenden Overload aus.

Für Workflow Definitionen, welche sich in einem Assembly befinden, stehen drei Methoden Overloads zur Verfügung, welche einen Typ als Parameter erwarten:

public WorkflowInstance CreateWorkflow(Type workflowType)

public WorkflowInstance CreateWorkflow(Type workflowType,
                                       Dictionary<string, Object> namedArgumentValues)

public WorkflowInstance CreateWorkflow(Type workflowType,
                                       Dictionary<string, Object> namedArgumentValues,
                                       Guid instanceId)

Wenn die Workflow Definitionen in XOML definiert sind, wählt man einen der anderen drei Overloads aus, welche einen XmlReader als Parameter erwarten. Der zweite XmlReader Parameter nimmt den Inhalt eines .rules files entgegen:

public WorkflowInstance CreateWorkflow(XmlReader workflowDefinitionReader)

public WorkflowInstance CreateWorkflow(XmlReader workflowDefinitionReader,
                                                 XmlReader rulesReader,
                                                 Dictionary<string, Object> namedArgumentValues)

public WorkflowInstance CreateWorkflow(XmlReader workflowDefinitionReader,
                                                 XmlReader rulesReader,
                                                 Dictionary<string, Object> namedArgumentValues,
                                                 Guid instanceId)

XOML basierte Workflows haben einige Vorteile, aber auch konzeptbedingt ein paar Einschränkungen:

  • Vorteil: Ein Workflow kann einfacher geändert werden. Dazu muss lediglich die XOML Datei oder wenn die Definition in einer Datenbank gehalten wird, der entsprechende Eintrag angepasst werden.
  • Vorteil: Die Regeln eines Workflows werden abenfalls in einer Datei (.rules) oder einem Record gehalten und können unabhängig vom Workflow aktualisiert werden. In Code basierten Workflows erfordert dies ein erneutes Kompilieren.
  • Vorteil: Die Workflow Definitionen müssen nicht kompiliert werden. Dies erleichtert das Management und die Verwaltung der Workflow Definitionen.
  • Nachteil: In den Workflow Definitionen können keine Properties definiert und keine Event Handler genutzt werden. Dies ist nur mit Code basierten Workflows möglich.

Nicht nur die XOML basierten Workflows enthalten meistens auch eigene Aktivitäten, welche in einem anderen Assembly bereitgestellt sind. Während der Entwicklung der Workflows wird lediglich ein Verweis auf diese Assemblies gesetzt, danach können die dort definierten Aktivitäten im Designer genutzt werden.
Wenn dieses Assembly nicht schon in der AppDomain der Workflow Runtime geladen ist, muss dies der WorkflowRuntime mitgeteilt werden. Dies erfolgt über einen TypeProvider, welcher der WorkflowRuntime als Service hinzugefügt wird:

WorkflowRuntime workflowRuntime = new WorkflowRuntime();

// Create a type provider for types referenced in the XOML
// which are not referenced by this project
TypeProvider typeProvider = new TypeProvider(workflowRuntime);

// Load referenced assemblies into the type provider
Assembly assembly = Assembly.Load("assemblyname");
typeProvider.AddAssembly(assembly);

// OR
// typeProvider.AddAssemblyReference(@"path to the assembly")

workflowRuntime.AddService(typeProvider);

Wenn dann eine Workflow Instanz mit einem der CreateWorkflow() Overloads erzeugt wird, wird die XOML basierte Workflow Definition validiert. Sollte dabei ein Problem auftreten, wird eine WorkflowValidationFailedException geworfen. Dies ist in der Dokumentation nur unter den Bemerkungen zu finden, die Exception wird nicht in der Liste der anderen Ausnahmen aufgeführt.
Die WorkflowValidationException besitzt ein Property Errors (Collection von ValidationError), welches genau Auskunft über die Probleme bei der Validierung der Workflow Definition gibt:

XmlReader workflowReader = XmlReader.Create("Workflow1.xoml");
WorkflowInstance workflowInstance = null;
try
{
    workflowInstance = workflowRuntime.CreateWorkflow(workflowReader);
    workflowInstance.Start();
}
catch (WorkflowValidationFailedException ex)
{
    foreach (ValidationError error in ex.Errors)
    {
        if (string.IsNullOrEmpty(error.PropertyName))
            Console.WriteLine("Validation error: {0}-{1}", error.ErrorNumber, error.ErrorText);
        else
            Console.WriteLine("Validation error for property \"{2}\": {0}-{1}", error.ErrorNumber, error.ErrorText, error.PropertyName);
    }
}

XOML Workflow Aktivierung mit Workflow Services

Wie funktioniert dies nun, wenn man Workflow Services einsetzt, und ebenfalls XOML basierte Workflows aktivieren möchte? Hier stellt sich auf den ersten Blick eine Art “Huhn-Ei Problem“. Der TypeProvider soll der WorkflowRuntime als Service hinzugefügt werden, diese existiert aber erst nach dem Erstellen des WorkflowServiceHosts. Man hat auch nicht direkten Zugriff auf die WorkflowRuntime, so dass nicht ohne weiteres ein Service hinzugefügt werden könnte.
Der Weg führt hier über die Verwendung einer eigenen WorkflowServiceHostFactory, welche einen eigenen WorkflowServiceHost erzeugt. Der Konstruktor dieses WorkflowServiceHosts ist sieben Mal überladen (plus einmal protected), dabei gibt es einen Konstruktor, welcher nebst dem Stream mit der Workflow Definition einen TypeProvider aufnimmt:

public WorkflowServiceHost(Stream workflowDefinition,
                           Stream ruleDefinition,
                           ITypeProvider typeProvider,
                           params Uri[] baseAddress)

Dieser TypeProvider kann nun wie folgt dem Konstruktor übergeben werden:

TypeProvider typeProvider = new TypeProvider(null);

// Load referenced assemblies into the type provider
Assembly assembly = Assembly.Load("assemblyname");
typeProvider.AddAssembly(assembly);

// OR
// typeProvider.AddAssemblyReference(@"path to the assembly")

Stream stream = new MemoryStream(ASCIIEncoding.Default.GetBytes("<MyXOML...>"));;
Uri uri = new Uri("myuri");

WorkflowServiceHost wfsh = new WorkflowServiceHost(stream, null, typeProvider, uri);

Der Konstruktor wirft nun bei Validierungsproblemen entgegen der Dokumentation ebenfalls eine WorkflowValidationFailedException, was so nicht in der Dokumentation steht, so dass man die Fehler entsprechend behandeln kann.

Workflow Library != Class Library

Montag, 6. Oktober 2008

In Visual Studio hat man beim Anlegen eines neuen Projektes die Auswahl zwischen vielen verschiedenen Projekttypen.

Visual Studio Projekttypen

Visual Studio WF Projekttypen

Wie vielerorts empfohlen, macht es bei Workflow Projekten meistens auch Sinn, die Runtime und die Workflow Definitionen in verschiedenen Assemblies abzulegen. Wenn man dann in einer Workflow Library eine neue Workflow Definition einfügen will, sind für die Items auch entsprechende Vorlagen verfügbar.

Wenn man aber mit einer normalen Class Library loslegt, und dann später gerne darin noch Workflow Definitionen oder eigene Activity Typen unterbringen möchte, funktioniert das nicht. Es reicht offenbar nicht aus, wenn man die entsprechenden Referenzen auf die WF Assemblies setzt.
Der Workflow Designer wirft einem eine nicht allzu aufschlussreiche Fehlermeldung “The service ‘System.Workflow.ComponentModel.Design.IIdentifierCreationService’ must be installed for this operation to succeed. Ensure that this service is available.” an den Kopf.

Weshalb? Eine Workflow Library ist doch nichts anderes als ein als DLL kompiliertes Assembly.
Man könnte nun ein neues Workflow Library Projekt anlegen, und alle vorhandenen Dateien hinüberziehen. Es gibt aber auch einen anderen Weg.

Beim Vergleich von zwei Projektfiles stellt man folgendes fest: Im ansonsten völlig identischen Projektfile (.csproj)  der Workflow Library findet man die folgenden zusätzlichen Einträge:

In der ersten PropertyGroup:
[Code language="XML"]{14822709-B5A1-4724-98CA-57A101D1B079};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}[/Code]

Zuunterst im Projektfile (Visual Studio 2008):

[Code language="XML"][/Code]

Für Visual Studio 2005 muss dieser Eintrag auf das .NET 3.0 Framework verweisen:

[Code language="XML"][/Code]

Man kann das Projektfile ausserhalb von Visual Studio bearbeiten, die IDE wird das Projekt automatisch aktualisieren. Danach stehen auch die WF Projektitems zur Verfügung.

Herzlich Willkommen!

Sonntag, 5. Oktober 2008

WordPress runterladen und beim Provider installieren: ca. 20 Minuten
Ein eigenes Theme erstellen: ein paar Stunden (*)
Mein neues Blog: unbezahlbar!

Herzlich Willkommen bei meinem neuen Blog! Ich habe mich ja vor vielen Monaten schon einmal im Bloggen versucht, dies aber mangels Motivation und Zeit dann wieder aufgegeben. Dies soll ein neuer Anlauf sein.

Dieses Blog nenne ich Technologie Backlog.
Weshalb? In meinem Beruf als Software Entwickler mache ich mir oft (mental) Notizen, wenn ich auf neue Technologien stosse oder sonst an ein interessantes Thema gerate. “Dies schaue ich mir dann später unbedingt an”.
Natürlich geschieht dies nur selten in der Tiefe und Breite, wie ich es gerne hätte. Und ich spreche hier nur von Dingen, die auch wirklich für die Ausübung meines Berufs wichtig sind. Die Technologien, die mich auch nebst der Arbeit interessieren, bringe ich kaum mehr unter einen Hut.
Mit diesem Blog versuche ich, interessantes über die Themen, mit denen ich mich befasse zu schreiben, und so die Technologien, welche mich interessieren etwas zu kommentieren. Momentan (Oktober 2008) ist dies Windows Communicatin Foundation (WCF) und Workflow Foundation (WF) im .NET 3.5 Framework. Es wird also zu Beginn wahrscheinlich vermehrt Einträge zu diesen Themen geben, aber über kurz oder lang werden auch andere Themen wie ASP.NET, WPF, klassische WinForms und andere (.NET) Technologien hier ihren Platz erhalten.

Ich werde versuchen, mindestens einmal pro Woche etwas zu schreiben. Die Ankündigung bei ein paar Kollegen, ein Hinweis auf meinem XING Profil und ein Link von der Firmen Site werden schon den nötigen Druck aufbauen, um das Ding hier am laufen zu halten.

Ich möchte hier nicht einfach Einträge von anderen Blogs zu kommentieren, sondern versuchen, wirklich eigenen Content zu erstellen. Natürlich werde ich ab und zu auch Branchen News und Trends kommentieren, und die liest man ja heutzutage oft in anderen Blogs.

Na dann geht’s los, ich freue mich über viele Kommentare!

(*) Die Suchfunktionalität muss ich noch einrichten, was ja im Moment noch nicht weiter schlimm ist, da die Anzahl Artikel noch überblickbar ist ;-)