F#, Funktionale Programmierung mit .NET, Teil 4

19. August 2008 – 20:51 von Andreas

In diesem Teil wird das Thema List Comprehensions behandelt:

List Comprehensions

List Comprehensions erleichtern einem das Erzeugen, Konvertieren und allgemein das Arbeiten mit “Collections”. Eine List Comprehension wird in F# mit zwei Punkten verwendet “..”. Links und Rechts zwischen diesen Punkten werden die oberen und unteren Grenzwerte angegeben (also [ STARTWERT .. ENDWERT ] ). So kann z.B. mit

  1. let numList = [ 0 .. 10 ]

folgende Liste erzeugt werden:
[ 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10 ]

Der Compiler übernimmt somit die Berechnung der dazwischen liegenden Elemente. In diesem Beispiel ist das nachfolgende Element immer um 1 größer als das davor Liegende. Die Schrittweite ist also bei default 1.

Die Verwendung von List Comprehensions ist aber auch bei alphanumerischen Zeichen möglich:

  1. let alphaList = [ ‘A’ .. ‘D’ ]

In alphaList stehen dann folgende Elemente:
[ ‘A’; ‘B’; ‘C’; ‘D’ ]

Ich habe aber auch die Möglichkeit die Schrittweite selbst zu beeinflussen, indem ich diese einfach mit angebe: [ STARTWERT .. SCHRITTWEITE .. ENDWERT ]
An einem konkreten Beispiel sieht dies so aus:

  1. let numList = [ 10 .. -1 .. 0 ]

Die erzeugte Liste enthält dann folgende Elemente:
[ 10; 9; 8; 7; 6; 5; 4; 3; 2; 1; 0 ]

List Comprehensions können auch in Schleifen verwendet werden, um eine neue Liste mit Hilfe einer anderen zu erstellen.
Am einfachsten ist dies anhand eines Beispiels zu sehen. Hier wird die Liste [ 2; 4; 6; 8; 10; 12; 14; 16; 18; 20 ] aus der Liste [ 1; 2; 3; 4; 5; 6; 7; 8; 9; 10 ] erzeugt:

  1. let doubles =
  2.     [ for x in 1 .. 10 -> x + x ]

Hierbei ist schön zu sehen, dass man die List Comprehension einfach in die for-Schleife einbauen kann, welche dann die zu erstellenende Liste kreiert.
Es besteht auch die Möglichkeit Bedingungen mit dem Schlüsselwort “when” einzubauen. In folgendem Beispiel verwenden wir dies, um im Bereich von 1 bis 10 eine Liste mit allen geraden Zahlen aufzubauen:

  1. let evennumbers =
  2.     [ for x in 1 .. 10 when x % 2 = 0 -> x ]

Zum Abschluss auch für dieses Thema eine kleine (mit Hilfe der List Comprehensions) zu lösende Aufgabe:
Schreibt eine Funktion “create_matrix”, welche als Paramater die Zeilen, Spalten und einen Initialwert enthält (also “let create_matrix(rows,cols,initvalue) = …” ). Die Funktion gibt eine Liste zurück, welche wiederum für jede Zeile der Matrix wiederum eine Liste enthält.
Wird die Funktion folgendermaßen aufgerufen: “create_matrix(3,4,0)” so sollte folgende Liste (welche die 3×4-Matrix repräsentiert) erstellt und zurückgegeben werden: [ [ 0; 0; 0; 0]; [ 0; 0; 0; 0]; [ 0; 0; 0; 0] ].
Außerdem wäre es schön wenn ihr noch eine Funktion printmatrix schreiben würdet, welche die Matrix formatiert auf der Konsole ausgibt:

  1. printmatrix(create_matrix(3,4,0))

Ausgabe:
Matrix:
[0; 0; 0; 0]
[0; 0; 0; 0]
[0; 0; 0; 0]

Eure Lösungen könnt ihr wie immer als Kommentar auf diesen Blogeintrag posten. Ich freue mich auf eure Einreichungen. Meine Lösung gibt es wie immer zu einem späteren Zeitpunkt als Blogeintrag. Aber jetzt seit erst einmal ihr gefragt;)…

C# 3.0 & LINQ - Workshopreihe: Slides, Demos, Sourcen

30. Juli 2008 – 00:17 von Andreas

Nachdem ich nun die 3-teilige C# 3.0 - Workshop - Reihe vollendet habe möchte ich euch die Slides, Demos und Sourcen hierfür nicht vorenthalten:

  • C# 3.0: C# goes functional, part1:
    - Einführung in C# 3.0
    - Automatic properties
    - Object initializers
    - Collection initializers
    - Implicitly-typed local variables
    - Lambda Expressions
    Slides
    Demos, Sourcen, Aufgaben

  • C# 3.0: C# goes functional, part2:
    - Anonymous types, Type inference
    - Extension methods (Inheritance vs. extension methods)
    - Partial methods
    - Anonymous recursion
    - Einführung in LINQ (Query Expressions, Expression Trees)
    - Quicksort in C# 3.0 revisited
    Slides
    Demos, Sourcen, Aufgaben

  • C# 3.0: C# and LINQ, part3:
    - Einführung in LINQ
    - Konzepte aus C# 3.0 für LINQ (Rückblick)
    - LINQ to Objects
    - Quicksort mit LINQ deklarativ
    - LINQ to XML
    - Expression Trees
    - Ausblick
    Slides
    Demos, Sourcen, Aufgaben

Weitere Teile sind geplant! (Hierbei könnte es um Themen wie z.B. ParallelLINQ oder LINQ in verteilten Anwendungen gehen…)

Zeitdruck, Stress und Erholung in der Softwareentwicklung

6. Juli 2008 – 13:15 von Andreas

Es ist jetzt ca. 4 Monate her, dass ich einen Blog-Eintrag verfasst habe. Ich bin in dieser Zeit einfach nicht dazu gekommen. Immer wenn ich mir vorgenommen hatte, endlich einen Eintrag zu verfassen (und ich hatte wirklich einige interessante Dinge!) kamen zich neue Aufgaben hinzu, welche eine höhere Priorität hatten. Mir macht das Software-Engineering wirklich Spaß und ich habe mein Hobby zum Beruf gemacht. Das Studium ist (bis auf ein paar kleine Ausnahmen;-) auch genau das, was mich interessiert! Trotzdem gab es in den letzten Wochen immer mal wieder Momente, an denen ich dachte “Puh, kann mal einer auf Pause drücken!”. Prüfungen, Projekte, Arbeit und Privatleben müssen erst einmal unter einen Hut gebracht werden. Ich komme manchmal von der Hochschule nach Hause und frage mich: “Was hast du heute eigentlich den ganzen Tag gemacht?” Nicht immer kann ich darauf eine sinnvolle Antwort geben. Es gibt Tage an denen ich zwar den ganzen Tag “herumwerkel”, aber nicht wirklich nennbare Fortschritte verzeichnen kann. Was mache ich da?
- Führe Gespräche mit anderen Kommilitonen
- Habe Projekt-Team-Meetings
- Lese Skripte oder Paper

Trotzdem sind diese Dinge sehr wichtig und gehören auch dazu! Bei Arbeiten, welche im Team durchgeführt werden ist Kommunikation das A und O! Das Problem ist nur, dass Abends dann die Aufgaben auf einen warten, welche am Tag nicht erledigt werden konnten.
Kann man produktiv arbeiten und die richtigen Entscheidungen treffen, wenn man von einem Termin zum nächsten hetzt? Ist es gut unter permanentem Stress zu arbeiten und sich keine Ruhepausen zu gönnen?
Ich denke nicht!
Erholung und Privatleben sind für ein gesundes und motiviertes Arbeiten enorm wichtig. Nein, sie sind nicht nur wichtig! Sie bilden die Grundlage für eine positive Einstellung zum Job und vor allem auch zum Leben! In der dotnetpro habe ich letztens einen Artikel über das bei Software-Entwicklern weit verbreitete Burnout-Syndrom gelesen. Dies muss doch für die IT-Branche ein Alarmsignal darstellen!

Deshalb sollten meiner Meinung nach folgende Dinge immer beachtet werden:

  • Ein wenig Stress und leichte Überforderungen können zu mehr Produktivität führen. Nimmt der Stress aber Überhand kann schnell genau die gegenteilige Wirkung entstehen.
  • Nach einer längeren anstrengenden Zeit muss eine Erholungsphase folgen.
  • Nicht “blind” alle Aufgaben annehmen, sondern sich auf die Wichtigsten konzentrieren.
  • Versuchen ein gutes Verhältnis zu seinen Kollegen / Kommilitonen aufzubauen.
  • Ein Hobby suchen, was nichts mit der eigentlich Arbeit zu tun hat, um auch mal wirklich Abstand vom Job zu bekommen.
  • Wenn man merkt, dass einem alles zu viel wird mit anderen vertrauten Personen darüber sprechen.

Und ab und zu sollte man sich auch mal die Zeit nehmen, um Blog-Einträge zu verfassen;-). Ich werde mich also bemühen wieder öfter zu posten und endlich mein F#-Tutorial fortzusetzen :-).

Java Client und .NET WebService Problem

30. April 2008 – 19:17 von Roy

Für die Vorlesung Web- und Multimedia-Systeme mussten wir ein Projekt erarbeiten und werden dies demnächst dann auch noch präsentieren müssen. Ein Komolitone und ich schlugen vor einen WebService mit dazugehörigen Clients, sowohl in WindowsForms als auch in ASP.NET zu entwickeln.
Der WebService sollte nur ein paar Methoden anbieten um Daten aus einer Datenbank zu holen und hineinzuschreiben. Die Datenbank ist in diesem Falle eine MySQL-Datenbank. Zunächst habe ich einen DAL (Data Access Layer oder auch Database Abstraction Layer) entwickelt. Man glaubt gar nicht wie unbekannt das Konzept eines DAL’s ist. Egal. In der Datenbank habe ich vier StoredProcedures angelegt über die Daten abgerufen und geschrieben werden können. Der WebService verweist nun auf den DAL und schleust die Daten an den Client und von dem Client an den DAL zur Datenbank durch.

Alle Komponenten (Schichten) sind in C#.NET 2.0 mit dem Visual Studio Express bzw. dem Visual Web Developer Express entwickelt worden. Um zeigen zu können das der WebService über Standard-Protokolle wie HTTP und SAOP kommuniziert und somit nicht an Microsoft Technologie gebunden ist wollte ich einen Java-Client mit NetBeans entwickeln der ähnlich dem WindowsForms-Client funktioniert. Eine schöne Anleitung zur WebService-Entwicklung in Java habe ich hier gefunden:

WebService in Java
http://www.theserverside.de/webservice-in-java/ [deutsch]

Da ich nur einen Client brauchte begann ich mit dem Kapitel “Implementation des WebService Clients”. Also Konsole aufgemacht und mit wsimport versucht die benötigten Service-Klassen für den Client zu erstellen. Folgendes bekam ich zu sehen:

wsimport_error

Dummerweise konnte ich damit gar nichts anfangen. Ich hatte eigentlich damit gerechnet das es einfach funktioniert. War aber eben nicht so. Aber wo jetzt anfangen nach einer Lösung zu suchen. Irgendwie scheint das Problem ja in der fettgedruckten Zeile der Dienstbeschreibung zu liegen.

<s:element name=”GetIPsResponse”>
<s:complexType>
<s:sequence>
<s:element minOccurs=”0″ maxOccurs=”1″ name=”GetIPsResult”>
<s:complexType>
<s:sequence>
<s:element ref=”s:schema”/>
<s:any/>
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>

Ein paar Google-Suchen später bin ich auf folgende Seite gestoßen die das Problem aufgreift und eine mögliche Lösung bietet:

DataSets and Web services don’t mix
http://searchsoa.techtarget.com/tip/0,289483,sid26_gci1048679,00.html [englisch]

Es lag an dem von mir verwendeten DataSet. Die Daten werden aus der Datenbank in ein DataSet geschrieben und aber den WebService an den Client übergeben. Ich hatte mich zwar schon gefragt wie Java damit umgehen würde aber auf die Idee, dass das Problem durch das DataSet verursacht wurde, bin ich nach neun Stunden Vorlesung nun auch nicht mehr gekommen.
Ich habe den beschriebenen Lösungsvorschlag umgesetzt indem ich testhalber mal nicht ein DataSet der Methode GetIPs zurückgab sondern ein String-Array. Und siehe da, dann klappt es auch mit wsimport.

wsimport_success

Eine interessante Idee kam noch von Andreas. Man sollte doch mal probieren ein typisiertes DataSet zu verwenden. Sobald ich dazu komme werd ich das auch noch machen. Probiert doch selbst mal und informiert mich über das Ergebnis.

Word oder LaTeX?

8. April 2008 – 21:00 von Roy

Vor ein paar Wochen hat meine letzte Theoriephase an der Berufsakademie begonnen. Das letzte Mal akademische Luft schnuppern, ich vermiss es jetzt schon. Danach schreib ich noch meine Diplomarbeit und dann ist es auch schon endgültig rum. Bevor ich aber in die endlosen Weiten der freien Marktwirtschaft abtauche muss ich eine sog. Studienarbeit verfassen (zu der ich sicher auch noch das ein oder andere bloggen werde). Für ganz Neugierige kann ich ja schon mal sagen um was es geht, bevor ich dann zum eigentlichen Thema komme. Ich soll den LEGO Mindstorms NXT-Baustein mit Java programmieren und einen kleinen Roboter oder einen Anlagenteil aufbauen. Mehr dazu später.
Ich hatte mir vorgenommen die Arbeit in LaTeX zu verfassen. Keine Ahnung wie ich darauf gekommen bin. Vielleicht lag es daran das ich mit Word schlechte Erfahrungen beim schreiben von größeren Arbeiten gemacht habe. Ich denke da nur mal an meine betriebliche Projektarbeit. Ich hätte Word am liebsten in die Tonne getreten. Ich gebe an dieser Stelle offen zu mich nie wirklich mit Word auseinandergesetzt zu haben. Heute musste ich mir von einem Komolitonen anhören das ich anscheinend zu wenig zu tun hätte um auf die Idee zu kommen die Studienarbeit mit LaTeX zu schreiben. Wir haben nicht weiter darüber diskutiert, ich hätte zu diesem Zeitpunkt sowieso keine Argumente für den Einsatz von LaTeX gehabt.

Ich mag Word. Wirklich. Auch wenn ich es für den oben erwähnten Zweck nie wieder einsetzen würde. Ich würde aber auch nie auf die Idee kommen einen kurzen Brief, z.B. eine Hassbrief an die GEZ, in LaTeX zu schreiben. Hier bevorzuge ich ganz klar Word. Ich sehe schon während dem schreiben wie das gedruckte Blatt Papier aussehen wird. Will man ganz sicher gehen kann man das ja auch noch mal in der Druckvorschau überprüfen. Schön ist auch das ich das Word-File an x-beliebige Menschen verschicken kann die es dann, sofern sie sich Word leisten konnten, öffnen und bearbeiten können. Word ist echt genial. Kaufen, auspacken, installieren, los schreiben.

Word ist leider nicht kostenlos. Selbst den Studenten werden für eine gültige Lizenz die letzten Kröten aus der Tasche gezogen. Ich hab sogar ein Buch über Word. Keine Ahnung wo das herkommt. Ich hab’s nicht gekauft. Ehrlich! In diesem Buch gibt es ein Kapitel das sinngemäß folgende Überschrift hat: “Lassen Sie Word die Formatierung übernehmen”. Toll. Aber das will ich doch gar nicht. Word interessiert sich leider nur wenig dafür was ich will. Selbst wenn ich versuche die Macht der Formatierung an mich zu reisen funkt mir Word dazwischen. Es ist egal ob ich erst eine Formatvorlage erstelle und dann schreibe oder erst schreibe und mich dann um die Formatierung kümmere, es kommt immer wieder zum Eklat zwischen mir und Word. Die optimale Reihenfolge von formatieren und schreiben hab ich noch nicht rausgefunden. Ein Beispiel zum mitmachen:

  1. Öffnet Word (sofern ihr es euch leisten konntet). Es sollte sich ein leeres Dokument aus der Formatvorlage normal.dot öffnen.
  2. Legt eine Kopfzeile an [Ansicht -> Kopf- und Fußzeile] und schreibt ein Wort rein. Danach den Kopfzeilen-Modus (oder wie auch immer sich das nennt) verlassen.
  3. Schreibt einen kleinen Text
  4. Markiert diesen Text und wählt aus dem Kontextmenü die Funktion [Absatz]
  5. In der Optionsgruppe [Abstand] ändert ihr den Wert für [Nach:] auf z.B. 100pt
  6. Mit [OK] bestätigen

OK, ein sehr primitives Beispiel, das sich auch leicht und zufriedenstellend anpassen lässt. Trotzdem, was hat die Kopfzeile mit dem eigentlichen Text zu tun. Ich würde erwarten, dass sich lediglich der markierte Text ändert.

LaTeX arbeitet da anders. So wie ich es gelernt hab, formatiert man zuerst das Layout. Passt das soweit kann man loslegen zu schreiben. Egal wo ich im Text jetzt Wörter, Sätze, ganze Abschnitte durch LaTeX übliche Kommandos formatiere, dass Layout des Dokuments bleibt wie es ist. Und alle anderen Textstellen auch. LaTeX ist im Gegensatz zu Word komplett umsonst (also im Sinne von kostenlos). Für arme Studenten wie mich also ein gefundenes Fressen. Ich benutze den Windows-Clon MikTeX und als Editor TeXnicCenter. Diesen kann ich außerdem ganz an meine Bedürfnisse anpassen. (s. Bild)

texniccenter.JPG

Versucht das mal in Word. Wenn ihr es schafft, was ja durchaus möglich sein könnte, dann druckt es bitte 100 mal aus und schickt es mir. LaTeX bietet mir den Vorteil, dass ich mich, nachdem ich das Layout EINMAL definiert habe, nur noch um den Inhalt kümmern muss.

Manchmal vermisse ich einen WYSIWYG-Editor ala Word trotzdem. Nicht jedes Kommando ist mir geläufig, da ich LaTeX ja nun auch nicht exzesiv einsetze. Die erzeugten PDF’s sehen echt toll aus. Das krieg ich aber auch mit Word und einem PDF-Printer noch hin. Auch die Weitergabe dieser *.tex-Files ist nicht so problemlos möglich wie mit Word. Schicke ich jemandem mein *.tex-File, der mit LaTeX auch was anfangen kann, dann hat dieser jemand vielleicht nicht eines dieser Packages die ich verwendet hab und muss nun erst rumsuchen um nur das PDF erstellen zu können. Alles schon erlebt.

Eigentlich sollte es ja egal sein was man verwendet, wichtig ist der Inhalt. Mir ist es aber lieber ich bekomme den Inhalt ohne den alltäglichen Wutausbruch wegen persönlicher Selbstverwirklichung von Word zu Papier.

Was bevorzugt ihr für kleine und große Texte? Wie auch immer, ich schreibe meine Studienarbeit in LaTeX. So, jetzt bau ich mir einen LEGO-Roboter der zum Kühlschrank rennt und mir ‘n kaltes Bier holt. Prost!

Form TransparencyKey auf [White] setzten

15. März 2008 – 22:25 von Roy

Gerade eben startete ich eine Anwendung an der ich gerade arbeite und bekam ungefähr folgendes Bild zu sehen:

Transparent_Window

Durch die Applikation hindurch konnte ich mein VisualStudio sehen und auch selektieren. Selbst durch den Fenstertitel konnte ich den Hintergrund sehen und per Mausklick dorthin wechseln. Irgendwie hatte ich erwartet, dass ich statt eines riesengroßen Lochs ein leeres Grid sehe. Herauszufinden wie das Grid verloren gehen konnte hat mich jetzt fast ne halbe Stunde Arbeit gekostet. Irgenwie hab ich die Eigenschaft TransparencyKey der Windows-Form auf [White] gesetzt.

Cooler Effekt aber ich kann grad nicht drüber lachen.

Policy Injection Application Block im Einsatz

8. März 2008 – 20:35 von Andreas

Die Enterprise Library ist eine feine Sache! Das offene Provider-Konzept ermöglicht es immer wieder neue Application Blocks lose gekoppelt und trotzdem gut intergriert zu implementieren. Ein schönes Beispiel für diese Integration bietet der (relativ ;) neue Policy Injection Application Block der Microsoft patterns & practices group. In diesem kleinen Beitrag möchte ich euch zeigen wie einfach man in seinem Code Excpetion-Handling einbringen kann ohne den eigentlichen “Business”-Code damit zu belasten (AOP lässt grüßen).

Nun aber zu einem praktischen Beispiel:
Zunächste laden wir die aktuelle Enterprise Library unter: Enterprise Library 3.1 - May 2007 herunter und installieren diese.
Dann legen wir ein neues Windows Forms-Projekt in VisualStudio an. Als nächstes benötigen wir eine App.config, in welcher die Konfiguration für die Enterprise Library, für unsere Applikation hineinkommt. In unser leeres WindowsForms-Projekt fügen wir nun eine Klasse für unsere “Business-Logik” ein. (Normal sollte dies natürlich in einem extra Projekt gemacht werden! Zu Demozwecken verzichten wir aber darauf.) Als nächstes ziehen wir einen Button auf das Formular und erstellen ein Click-Ereignis für diesen Button. Darin wird dann unser Business-Logik-Code aufgerufen.
In diesem Beispiel wollen wir mit Hilfe der Enterprise Library bei einer Exception, Informationen über den Fehler in einer MessageBox ausgeben. Um auf die entsprechenden Klassen der Enterprise Library zugreifen zu können benötigen wir noch die richtigen Assembly-Referenzen und Namespaces. Folgende DLLs müssen also für unser Beispiel eingebunden werden (diese befinden sich unter [”Installationsverzeichnis”\Microsoft Enterprise Library 3.1 - May 2007\Bin]):

Der komplette Code für die “Business”-Klasse und das Formular mit unserem Click-Ereignis sollte folgendermaßen aussehen:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using Microsoft.Practices.EnterpriseLibrary.PolicyInjection;
  10. using Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers;
  11. using WinFormsMessageBoxExceptionHandler;
  12.  
  13. namespace WindowsFormsPolicyInjectionTest
  14. {
  15.     public partial class Form1 : Form
  16.     {
  17.         public Form1()
  18.         {
  19.             InitializeComponent();
  20.         }
  21.  
  22.         private void button1_Click(object sender, EventArgs e)
  23.         {
  24.             // BusinessLogicClass-Instanz ueber die PolicyInjection-
  25.             // Klasse erzeugen lassen, so dass die konfigurierten Policies
  26.             // als Aspekte (siehe Aspektorientierte Programmierung) die
  27.             // auf BusinessLogicClass-Instanz zugreifen koennen.
  28.             BusinessLogicClass bl = PolicyInjection.Create<BusinessLogicClass>();
  29.             bl.Foo();
  30.         }
  31.     }
  32.  
  33.     class BusinessLogicClass : MarshalByRefObject
  34.     {
  35.         public void Foo()
  36.         {
  37.             MessageBox.Show("Hello");
  38.             throw new Exception("bad exception ;)");
  39.         }
  40.     }
  41. }

Schauen wir uns zuerst die “BusinessLogicClass”-Klasse an. Sofort fällt auf, dass sie von MarshalByRefObject erbt. Dies müssen wir machen, um die Methoden der Klasse (in userem Fall die Methode Foo()) vom Policy Injection Block “abfangbar” zu machen. In der Konfiguration des Policy Injection Blocks kann ich nämlich per Regel festlegen, welche Methoden/Klassen die Handler der Policy verarbeiten sollen. Bearbeiten wir also nun unsere App.config mit Hilfe des Tools EntLibConfig.exe (zu finden unter [”Installationsverzeichnis”\Microsoft Enterprise Library 3.1 - May 2007\Bin]). Nachdem die App.config in EntLibConfig.exe geöffnet fügen wir den Policy Injection Application Block hinzu:

Als nächstes müssen wir dem Block eine Policy hinzufügen:

Nun müssen wir der neu erstellten Policy sagen, wann diese eingreifen soll. Da wir wollen, dass Sie bei allen Methoden unserer “Business”-Klasse reagieren soll, wählen wir als “Matching Rule” die “Type Matching Rule”:

Nun müssen wir noch die genaue Klasse festlegen, auf welche die “Type Matching Rule” reagieren soll (Die Reihenfolge der Aktionen ist auf dem Bild nummeriert):

Nun haben wir also festgelegt auf welche Klasse die Policy schauen soll. Jetzt benötigen wir noch einen geeigneten Handler. Da der Handler eine Excpetion abfangen soll wählen wir den vordefinierten “Exception Handling Handler”:

Bisher haben wir uns nur um den Policy Application Block gekümmert und hierfür entsprechende Konfigurationen durchgeführt. Wir benötigen aber noch den Exception Handling Block, der die eigentliche Excpetion behandeln und mit dem “Exception Handling Handler” der soeben erstellten Policy verbunden werden soll. Hierzu fügen wir zuerst den Exception Handling Application Block hinzu:

Diesem Block fügen wir dann eine “Exception Policy” hinzu:

Dieser Policy müssen wir sagen, auf welchen Exception-Type sie reagieren soll (in unserem Fall eine normale Excpetion):

Da wir wollen, dass Informationen über die geworfene Excpetion in einer MessageBox ausgegeben werden sollen und die Exception danach nicht mehr weitergeworfen werden soll müssen wir dieses Verhalten auch konfigurieren:

Da es keinen vordefinierten Handler gibt, welcher Informationen über eine Exception in einer MessageBox ausgibt müssen wir einen eigenen “Custom Handler” implementieren. Zuerst legen wir den Custom Handler aber in unserer Konfiguration an:

Kommen wir nun also zum Implementieren des Custom Handlers. Hierzu erstellen wir ein neues Klassenblibliotheks-Projekt in VisualStudio. Das Projekt benötigt folgende Referenzen:

Wir nennen unseren Custom Handler “WinFormsMessageBoxExceptionHandler”. Die Implementierung enthält folgenden Code:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Windows.Forms;
  5. using Microsoft.Practices.EnterpriseLibrary.Common;
  6. using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
  7. using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
  8. using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration;
  9. using System.Collections.Specialized;
  10.  
  11. namespace WinFormsMessageBoxExceptionHandler
  12. {
  13.     [ConfigurationElementType(typeof(CustomHandlerData))]
  14.     public class MessageBoxExceptionHandler : IExceptionHandler
  15.     {
  16.  
  17.         public MessageBoxExceptionHandler(NameValueCollection collection)
  18.         {
  19.         }
  20.  
  21.         #region IExceptionHandler Members
  22.  
  23.         public Exception HandleException(Exception exception, Guid handlingInstanceId)
  24.         {
  25.             MessageBox.Show("Following error occurs: " + exception.Message
  26.                             ,"Error"
  27.                             , MessageBoxButtons.OK
  28.                             , MessageBoxIcon.Error);
  29.             return exception;
  30.         }
  31.  
  32.         #endregion
  33.     }
  34. }

Unsere Custom Handler-Klasse “MessageBoxExceptionHandler” muss das Interface “IExceptionHandler” und dort die Methode “HandleException” implementiern. “HandleException” bekommt die geworfene Exception als Parameter übergen und gibt dann wieder eine Exception zurück. Wir geben die Informationen der ursprünglich geworfenen Excpetion per MessageBox aus und die Excpetion selber einfach ohne Veränderung wieder zurück. Außerdem benötigt die Klasse “”MessageBoxExceptionHandler” einen Konstruktor mit einem “NameValueCollection”-Parameter haben. Zusätzlich hierzu muss der Klasse noch folgendes Klassen-Attribut hinzugefügt werden: [ConfigurationElementType(typeof(CustomHandlerData))]
Zuletzt MUSS die Assembly noch mit einem “strong name key file” signiert werden (ansonsten erhält man folgende Fehlermeldung beim Versuch des Ladens der Assembly: “There were no types found in the assembly “AssemblyName” that implement or inherit from the base type “Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.IExceptionHandler”):

So, das wäre geschafft! Jetzt müssen wir das Projekt noch builden und können dann unseren Custom Handler in die Konfiguration einbauen. Dies tun wir, indem wir die “Type”-Eigenschaft des Custom Handlers entsprechend auf unseren selbst erstellten “WinFormsMessageBoxExceptionHandler” setzen:

Als letztes müssen wir nun noch unseren “Exception Handling Handler” aus dem Policy Injection Application Block mit der “Exception Policy” aus dem Exception Handling Application Block verknüpfen. Dies machen wir hier:

Es scheint geschafft zu sein. Wir können die Konfiguration speichern und unsere Arbeit testen. Aber halt!! Unsere “WinFormsMessageBoxExceptionHandler”-Assemby muss auch noch in unserem Implementierungsprojekt referenziert werden:

Jetzt können wir unsere Test-WinForms-Anwendung aber endlich starten und testen. Und siehe da, nachdem der Button geklickt wurde und die Zeile “throw new Exception(”bad exception ;)”);” abgearbeitet wurde bekommen wir unsere MessageBox:

Wie man sieht konnten wir das Exception-Handling schön von dem eigentlichen Implementierungs-Code auslagern und zudem noch konfigurabel machen. Weitere sinnvolle Szenarien, wie Logging, usw. lassen sich natürlich auf die gleiche Weise wunderbar abbilden.

Da kann ich nur viel Spaß mit dem Policy Injection Application Block wünschen ;).

JavaScript Fehler auf CRM-Seiten, nach Microsoft CRM 4.0 Installation

29. Februar 2008 – 20:26 von Andreas

Heute haben wir die neue Version von Microsofts CRM-System mit Namen “MS Dynamics CRM 4.0″ auf einem Windows Server 2003, R2, SP2 installiert. Die Installaltion an sicher verlief eigentlich ohne große Probleme. Nachdem dann alles fertig war, wollte ich den Zugriff testen und bin per Web-Access, über den IE auf die CRM-Startseite gegangen. Leider musste ich feststellen, dass auf manchen Seiten die Bilder nicht angezeigt werden konnten und JavaScript-Fehler aufgetreten waren. Beim JavaScript-Fehler handelte es sich u.a. um folgende Meldung: “Object expected”.

Nach ewigem Rumsuchen, 2 Neuinstallationen usw. glaubte ich nicht mehr daran das Problem beheben zu können;). Dann bin ich im Netz glücklicherweise aber auf folgenden Link gestoßen: http://www.themssforum.com/Crm/Error-Pageloading/

Hier gab es jemand, der wohl das selbe Problem wie ich hatte! Ganz unten im Beitrag postete jemand die lang ersehnte Lösung, welche auch bei mir funktionieren sollte:

“Hi, I had the same issue. What I did is went to the Properties of the website (in IIS) on
which CRM 4.0 is configured. There I selected Directory Security. Unchecked
Anonymus Access, Click Ok And Apply. Then Again went to the same place,
Directory Security, and again checked the Anonymus Access, clicked Ok and
Apply. This at least worked for me. ”

Es schien ein Berechtigungs-/Security- Problem zu sein. Also: Checkbox rein, Übernehmen, Checkbox raus, Übernehmen, Browser aktualisieren und siehe da alles geht:). Dies hatte mich ca. einen halben Tag gekostet. Aber naja, wieder was gelernt:).

technetbloggers.de hat Geburtstag …

25. Februar 2008 – 18:28 von Roy

… und fast hätten wir es vergessen. Heute vor einem Jahr gaben Andreas und ich der Idee gemeinsam zu bloggen ein Namen: „technetbloggers.de“

Ein Jahr ist also rum. Hier mal eine kurze Historie und eine kleine Statistik:

  • Andreas und ich treffen uns, nach jahrelanger Trennung, auf einer bekannten Studentenplattform wieder und beschließen gemeinsame Sache zu machen.
  • Am 25. Februar 2007 wird der erste Blogeintrag von Andreas verfasst und online gestellt.
  • Nachdem sich unser damaliger Provider auf Grund gestiegener Stromkosten gezwungen sah die Preise zu erhöhen sahen wir uns gezwungen umzuziehen.
  • Im Rahmen diese Umzugs am 24. November wechselten wir auch gleich die Plattform, mit der wir denke ich beide besser klar kommen, und das darunter liegende Betriebssystem.
  • Seitdem wird nun ein Blog nach dem anderen verfasst, wenn auch mit längeren Pausen

Hier nun die kleine Statistik:

  • Wir haben insgesamt bisher 60 Blogeinträge verfasst.
    • 40 von Andreas
    • 20 von Roy
  • Insgesamt wurden 69 Kommentare zu den Einträgen abgegeben
  • Auf der neuen Plattform hatten wir bis heute 1925 Besucher.

Ist ja eigentlich auch egal. Ich wollte es ja nur mal erwähnen (nur falls jemand gerne gratulieren will).

C# like F#

24. Februar 2008 – 17:49 von Andreas

In meinem vorherigen Post (F# Teil 3) habe ich unter anderem die Methode “iter” der F#-Klasse List verwendet. Darauf hatte Aaron als Kommentar auf meinen Eintrag folgende ähnliche Lösung in Ruby gepostet:

Code von Aaron:

>> ergebnis = lambda {|x, y| x*y }.call(2, 4)
=> 8
>> list = [”1″, “2″] + [] + [”3″]
=> [”1″, “2″, “3″]
>> printListItems = proc {|list| list.each {|i|
?> puts “Element der Liste: ” + i
>> }}
=> #
>> printListItems.call(list)
Element der Liste: 1
Element der Liste: 2
Element der Liste: 3
=> [”1″, “2″, “3″]

Zur Erinnerung: Die “iter”-Funktion erhält als Argumente eine Funktion und eine Liste. Sie wendet dann die übergebene Funktion auf jedes Element der Liste an. Warum die C#-Listen-Klasse nicht um die F#-”iter”-Funktion erweitern (als Extension Method). Genau dies habe ich nun getan! Den Code hierzu (und einen kleinen Testaufruf) möchte ich euch nicht vorenthalten:):

  1. public static class ExtensionMethods
  2.     {
  3.         /// <summary>
  4.         /// Funktionszeiger fuer eine generische
  5.         /// Funtkion mit einem Parameter und keinem
  6.         /// Rueckgabewert.
  7.         /// </summary>
  8.         /// <typeparam name="T">Typ des Parameters.</typeparam>
  9.         /// <param name="arg0">Parameter der Funktion.</param>
  10.         public delegate void Func<T>(T arg0);
  11.  
  12.         /// <summary>
  13.         /// Die iter-Funktion erhaelt als Argumente eine Funktion
  14.         /// und eine Liste. Sie wendet dann die uebergebene Funktion
  15.         /// auf jedes Element der Liste an.
  16.         /// </summary>
  17.         /// <typeparam name="T">Typ der Elemente, der Liste.</typeparam>
  18.         /// <param name="l">Extension-Method auf die C#-List-Class.</param>
  19.         /// <param name="func">Die Funktion, welche auf die Listenelemente
  20.         /// angewendet werden soll.</param>
  21.         public static void iter<T>(this List<T> l, Func<T> func)
  22.         {
  23.             // Ueber die Elemente der Liste iterieren
  24.             l.ForEach((T element) =>
  25.             {  
  26.                 // Die Funktion auf das jeweilige Element anwenden.
  27.                 func(element);
  28.             });
  29.         }
  30.     }
  31.  
  32.     class Program
  33.     {  
  34.  
  35.         static void Main(string[] args)
  36.         {
  37.             // Neue string-Liste erstellen
  38.             var list = new List<string>() { "Andi ", "Maier" };
  39.             // Verwendung der iter-Funktion:
  40.             // Die Funktion "Console.Write" auf die string-
  41.             // Elemente anwenden.
  42.             list.iter<string>(Console.Write);
  43.  
  44.             Console.ReadLine();
  45.         }
  46.     }