Rainbird´s Blog<a href="http://www.xing.com/profile/Hagen_Siegel" target="_blank"><img src="http://www.xing.com/img/buttons/1_de_btn.gif" width="85" height="23" alt="XING" border="0" /></a> Profil von Rainbird öffnen
http://brightyellow.de/blogs/rainbird/atom.aspxCommunity Server2008-03-10T06:49:00ZZyan 2.0http://brightyellow.de/blogs/rainbird/archive/2011/06/14/zyan-2-0.aspx2011-06-14T21:28:00Z2011-06-14T21:28:00Z<p>Die zweite Version meines Kommunikationsframeworks Zyan ist draußen. Als wichtigste Neuerungen gib´s verteilte LINQ-Unterstützung und bi-direktionale TCP-Kommunkation. Ein kurzer Überblick mit Beispiel-Codesnippets findet sich unter <a href="http://zyan.codeplex.com/wikipage?title=Was%20ist%20neu%20in%20Zyan%202.0%3f&referringTitle=Deutsche%20Dokumentation">http://zyan.codeplex.com/wikipage?title=Was%20ist%20neu%20in%20Zyan%202.0%3f&referringTitle=Deutsche%20Dokumentation</a>. </p>
<p>Zyan 2.0 läuft auch problemlos in der Cloud. Momentan läuft eine auf Microsoft Azure gehostete Version des Zyan-MiniChat-Beispiels (Order <strong>examples\Zyan.Examples.MiniChat</strong> im Repository). Einfach mal ausprobieren, mit dem MiniChat-Client (aus der Beispiel-Anwendung). Als Server-URL <strong>tcpex://ZyanMiniChat.cloudapp.net:9010/MiniChat</strong> auswählen. Das Beispiel läuft auf einem Azure-Testaccount, der nach Ablauf der kostenlosen Nutzungsdauer wieder gelöscht werden wird. </p>
<p>Ein Snippet, wie man die eigene Zyan-Anwendung mit wenigen Zeilen Code in Azure laufen lassen kann, gibt´s hier: <a href="http://zyan.codeplex.com/discussions/259397">http://zyan.codeplex.com/discussions/259397</a>.</p>
<p>Für die schnelle und einfache Integration in eigene Projekte, ist Zyan 2.0 nun auch als NuGet Paket verfügbar: <a href="http://nuget.org/List/Packages/Zyan">http://nuget.org/List/Packages/Zyan</a>.</p>
<p>Ich freue mich über Feedback und Fragen zu Zyan 2.0. Bitte das Zyan-Diskussionsforum benutzen: <a href="http://zyan.codeplex.com/discussions">http://zyan.codeplex.com/discussions</a>.</p><img src="http://brightyellow.de/aggbug.aspx?PostID=64" width="1" height="1">Rainbirdhttp://brightyellow.de/members/Rainbird.aspxZyan 1.0 ist fertig!http://brightyellow.de/blogs/rainbird/archive/2010/12/20/zyan-1-0-ist-fertig.aspx2010-12-20T19:55:00Z2010-12-20T19:55:00Z<p>Nach guten drei Monaten steht das fertige Kommunikationsframework Zyan, in der Version 1.0, zum <a title="Download" href="http://zyan.codeplex.com/releases/view/57797" target="_blank">Download</a> bereit.</p>
<p>Zyan ist für alle interessant, die verteilte .NET-Anwendungen entwicklen oder erst noch entwicklen wollen. Dabei spiel es keine Rolle, ob im LAN oder übers Internet kommuniziert werden soll. Der große Unterschied zu den üblichen Verdächtigen <em>(WCF, ASP.NET Webservices, Sockets, .NET Remoting)</em> liegt in der <strong>Einfachheit</strong>. Diese Einfachheit lässt sich mit folgenden Stichpunkten beschreiben:</p>
<ul>
<li>
<div>Keine Konfigurationsdateien!</div></li>
<li>
<div>Klassen müssen <u>nicht</u> von einer speziellen Basisklasse <em>(wie z.B. MarshalByRefObj)</em> abgeleitet werden, um übers Netzwerk aufgerufen werden zu können</div></li>
<li>
<div>Keine deklarativen Attribute nötig <em>(wie z.B. bei WCF üblich) </em></div></li>
<li>
<div>Standard-Konfiguration kommt auf Server- und Clientseite jeweils mit einem Dreizeiler aus</div></li></ul>
<p>Wie einfach man mit Zyan verteilte Anwendungen entwickeln kann, zeigt folgendes Einstiegsbeispiel: <a title="Erste Schritte mit Zyan" href="http://zyan.codeplex.com/wikipage?title=Erste%20Schritte&referringTitle=Deutsche%20Dokumentation">Erste Schritte mit Zyan</a> </p>
<p>Aber Zyan ist nicht nur einfach, sondern auch leicht erweiterbar und vielseitig. Für die meisten Probleme, die Entwickler verteilter Anwendungen haben, bringt Zyan fertige Komponenten mit. Wenn diese für den eigenen Anwendungsfall doch nicht passen, kann man. mit wenig Aufwand, eigene Erweiterungen für Zyan schreiben. Folgende Features sind in Zyan enthalten:</p>
<ul>
<li>
<div>Systemanforderungen</div></li>
<ul>
<li>
<div>Auch auf dem Server nur .NET 3.5 Client Profile nötig</div></li>
<li>
<div>Läuft auch unter mono </div></li></ul>
<li>
<div>Protokolle</div></li>
<ul>
<li>
<div>Schnelle binäre TCP-Kommunikation</div></li>
<li>
<div>Kommunikation über HTTP mit binärer Serialisierung</div></li>
<li>
<div>Interprozesskommunikation über Named Pipes</div></li>
<li>
<div>Schnittstellen zur Erweiterung des Systems um eigene Protokolle </div></li></ul>
<li>
<div>Authentifizierung</div></li>
<ul>
<li>
<div>Authentifizierung mit Benutzername und Kennwort eines Windows-Benutzers des Servers</div></li>
<li>
<div>Single-Sign-On Authentifizierung mit Windows-Benutzer über SSPI</div></li>
<li>
<div>IAuthenticationProvider-Schnittstelle zur Anbindung benutzerdefinierter Authentifizierungssysteme</div></li></ul>
<li>
<div>Kommunikationssicherheit</div></li>
<ul>
<li>
<div>Verschlüsselte und Signierte Netzwerkkommunikation mit Kerberos oder NTLM in Verbindung mit Active Directory</div></li>
<li>
<div>Verschlüsselte Netzwerkkommunikation mit symmetrisch verschlüsselten asymetrischen Schlüsseln (keine Zertifikate nötig!)</div></li></ul>
<li>
<div>Sitzungsverwaltung</div></li>
<ul>
<li>
<div>Schnelle In-Memory Sitzungen</div></li>
<li>
<div>oder skalierbare SQL Server gespeicherte Sitzungen <em>(Selbe Sitzung über mehrere Applikationsserver hinweg möglich)</em></div></li>
<li>
<div>Unterstützung für Sitzungsvariablen</div></li>
<li>
<div>ISessionManager-Schnittstelle zur Anbindung einer benutzerdefinierten Sitzungsverwaltung</div></li></ul>
<li>
<div>Komponentenfeatures</div></li>
<ul>
<li>
<div>Verwaltung der entfernt zugreifbaren Komponenten in Komponenten-Katalogen</div></li>
<li>
<div>Vielfältige Möglichkeiten zur Objektaktivierung <em>(automatisch, Singleton, über eigene Factory)</em></div></li>
<li>
<div>Intuitive Unterstützung von verteilten Event Based Components <em>(</em><a title="Verteiltes EBC-Beispiel mit Zyan" href="http://zyan.codeplex.com/wikipage?title=Verteilte%20Event%20Based%20Components%20mit%20Zyan%20erstellen&referringTitle=Deutsche%20Dokumentation" target="_blank"><em>Verteiltes EBC-Beispiel mit Zyan</em></a><em>)</em></div></li></ul></ul>
<p><u>Hinweis:</u> <br />Zyan hat nichts mit Webservices oder SOAP oder dergleichen am Hut. Zyan ist nur für Kommunikation zwischen .NET-Komponenten gedacht. Für die Kommunikation mit anderen Plattformen <em>(z.B. Java)</em> bietet Zyan <u>derzeit</u> keine Unterstützung an. </p>
<p>Zyan kostet übrigens nix und auch der <a title="Quellcode" href="http://zyan.codeplex.com/SourceControl/changeset/view/7623">Quellcode ist frei verfügbar</a>. Ihr könnt damit alles treiben, was Ihr wollt <em>(Zyan steht unter MIT Lizenz).</em></p>
<p>Für Fragen zum Zyan Projekt stehe ich gerne zur Verfügung. Hier gehts zum Zyan-Diskussionsforum: <a href="http://zyan.codeplex.com/discussions">http://zyan.codeplex.com/discussions</a><br />Ich freue mich übrigens über jeden gemeldeten Bug: <a title="Zyan Issue Tracking" href="http://zyan.codeplex.com/workitem/list/basic">Zyan Issue Tracking</a></p>
<p>- Hagen Siegel</p><img src="http://brightyellow.de/aggbug.aspx?PostID=62" width="1" height="1">Rainbirdhttp://brightyellow.de/members/Rainbird.aspxentrastructurehttp://brightyellow.de/blogs/rainbird/archive/2009/11/04/entrastructure.aspx2009-11-04T00:14:00Z2009-11-04T00:14:00Z<p>Es ist soweit! Meine Gedanken zu einer freien Plattform für Business Software nehmen Form an.<br />Allgemeine Frameworks wie z.B. das .NET Framework sind zwar cool, bieten aber keine vollständige Infrastruktur für Geschäftsanwendungen. Zu vieles ist da noch Handarbeit.<br />Fertige ERP/CRM/SCM-Systeme sind zwar anpassbar, bieten meistens aber zu wenige Möglichkeiten, um eigene Erweiterungen zu schreiben. Im .NET-Bereich sieht es mit ERP & Co. eh sehr mau aus. Noch nicht einmal Microsoft kann ein System anbieten, welches wirklich mit .NET-Technologie aufgebaut ist. </p>
<p>Abhilfe könnte da entrastrucure (free enterprise Infrastructure) schaffen. Es handelt sich dabei um ein freies Software-Projekt, welches nicht etwa ein neues ERP-System wird, sondern eine Plattform für solche und änliche Anwendungen. Die Entwicklung hat gerade erst begonnen!</p>
<p>Wer sich dafür interessiert, findet alle Infos inkl. Source Code unter <a href="http://entrastructure.codeplex.com/">http://entrastructure.codeplex.com</a>.</p>
<p> </p><img src="http://brightyellow.de/aggbug.aspx?PostID=60" width="1" height="1">Rainbirdhttp://brightyellow.de/members/Rainbird.aspxBug in Visual Studio 2008: n-Tier-DataSets funktionieren nicht mit Projektmappenordnernhttp://brightyellow.de/blogs/rainbird/archive/2009/01/20/bug-in-visual-studio-2008-n-tier-datasets-funktionieren-nicht-mit-projektmappenordnern.aspx2009-01-20T19:41:00Z2009-01-20T19:41:00Z<p>Erst kürzlich habe ich Microsoft noch gelobt, dass sie in Visual Studio 2008 eine Möglichkeit geschaffen haben, TableAdapter von der DataSet-Definition zu trennen und beides in getrennten Projekten unterzubringen. Nun muss ich <em>(nach einem freundlichen Hinweis aus der myCSharp.de-Community)</em> dieses Lob leider wieder nach unten korrigieren. Das Ganze funktioniert nämlich nicht, wenn die Projekte in Projektmappen-Ordnern liegen. <img src="http://yellow-rainbird.de/emoticons/emotion-6.gif" alt="Sad" /></p>
<p>Details zu diesem Bug und der aktuelle Status sind hier nachzulesen: <a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=378368">https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=378368</a></p><img src="http://brightyellow.de/aggbug.aspx?PostID=57" width="1" height="1">Rainbirdhttp://brightyellow.de/members/Rainbird.aspxEine kleine Geschichte zum Thema RowState und OR-Mapperhttp://brightyellow.de/blogs/rainbird/archive/2009/01/09/habe-sehnsucht-nach-dem-rowstate.aspx2009-01-09T21:42:00Z2009-01-09T21:42:00Z<p>Zu Zeiten von .NET 1.x und 2.0 war die Welt noch einfach. Frei Haus gab es genau Eine Datenzugriffstechnologie, nämlich ADO.NET. Die gibt es natürlich immernoch, aber mittlerweile sind noch Linq2SQL und das Entity Framework dazugekommen. Die Beiden Neuen sind "echte" OR-Mapper, da sie Resultsets in Form von herkömmlichen .NET Objekten ausspucken. Das Entity Framework arbeitet sogar mit einer eingezogenen Abstraktionsebene und verspricht Datenzugriffslogik unabhängig vom RDBMS implementieren zu können. SQL ist out, Linq ist in! Visual Studio rundet das Ganze mit komfortablen Designern und Assistenten ab. Auch die SOAP-Freunde machen die neuen Datenschaufler glücklich, müssen sie sich doch nicht mehr mit XML-Serialisierung von properitären DataSets herumschlagen, die alles andere als interoperabel sind. Man kann also durchaus sagen: Das lange warten auf die OR-Mapping-Lösung von Microsoft hat sich gelohnt. Viele Probleme können mit den neuen Datenzugriffstechnologieen elegant gelöst werden.</p>
<p>Ganz so rosarot ist die Welt dann aber doch nicht. Eine Sache stößt mir sehr bitter auf, wenn ich z.B. mit dem Entity Framework arbeite: Es gibt keinen RowState! </p>
<p>Im guten alten ADO.NET ist RowState der Name einer Eigenschaft der Klasse DataRow. Eine DataRow beschreibt einen einzelnen Datensatz, der von einer Datenquelle abgerufen wurde und innerhalb einer DataTable lokal im Arbeitsspeicher liegt. Aber das ist wohl den meisten bekannt. Zurück zum RowState. Der RowState gibt an, ob die DataRow geändert, gelöscht, neuangelegt oder unverändert ist. Man kann deshalb auch sagen: Eine DataTable weiß, welche ihrer DataRows, geändert, gelöscht oder neuangelegt sind. Das ist sehr nützlich. Wenn ich z.B. eine DataTable an ein DataGridView (Windows.Forms) gebunden habe und dort als Benutzer einer Zeile lösche, ist diese Zeile in der DataTable nicht verloren, sondern der RowState wird auf "Gelöscht" (<strong><em>deleted</em></strong>) gesetzt. Wenn ich im selben DataGridView nun eine neue Zeile eingebe, erhält die dadurch erzeugte DataRow den RowState "Neuangelegt" (<strong><em>added</em></strong>). Ändere ich einen Wert in einer vorhanden Zeile, hat diese danach logischerweise den RowState "Geändert" (<strong><em>modified</em></strong>). Die DataRow weiß aber noch mehr über sich selbst. Sie kennt nicht nur ihren aktuellen Zustand, sondern merkt sich auch die Originalwerte (also z.B. vor der Änderung durch den Benutzer). Das ermöglicht es wiederum durch einfaches aufrufen der RejectChanges-Methode an der DataTable, alles sofort Rückgängig zu machen. Die neuangelegte Zeile verschwindet wieder, die Gelöschte taucht wieder auf und die die Geänderte hat auch wieder ihre alten Werte. "Na und? Das ist doch alles ein alter Hut. Das ist doch allgemein bekannt!" werden jetzt einige denken. Ich stimme zu. Es ist ein alter Hut. Das gab es auch schon alles bei Classic ADO. Also ist es nach so vielen Jahren doch eine Selbstverständlichkeit.</p>
<p>Jetzt aber die große Frage: <strong>Wie mache ich das, wenn ich einen OR-Mapper benutze?</strong> Platte Objekte haben keinen RowState! Sie wissen nicht, ob sie gelöscht oder neuangelegt wurden. Sie wissen auch nicht, ob sie geändert wurden. Noch nicht mal ihre alten Werte vor der Änderung können sie sich merken. Wenn es die Objekte aber selber nicht können, muss es jemand Anderes für sie machen. Genau! Die OR-Mapping-Infrastruktur. Die wischt unaufgefordert jede kleine Träne von unseren Wangen. Beim Entity Framework kümmert sich der ObjectContext um diese RowState-Angelegenheiten. Als aufmerksamer Kontext kennt er alle Objekte, die er erzeugt hat beim Namen und führt über jedes Einzelne genau Protokoll. Das funktioniert auch super. Aber was ist mit der RejectChanges-Methode? Dafür gibt es leider beim DataContext keine Entsprechung. Wenn ich meine Änderungen verwerfen will, muss ich entweder vorher eine komplette Kopie der Objektliste erstellen und diese für eine mögliche Wiederherstellung des Originalzustandes im Speicher halten. Oder ich rufe einfach die Daten nochmal vom Datenbank-Server ab. Letzteres ist verglichen mit meiner RejectChanges-Lösung aber sehr ressourcenfressend. Scheidet damit aus. Ersteres ist Umständlich und erfordert einiges an Zusatzcode (Die Sicherheitskopie der Objektliste muss dann ja dem ObjectContext erst wieder beigebracht werden). Wie sieht es mit dem DataBinding in meinem Windows.Forms-Formular aus? Ähm... Genau! Auch da muss ich rumfummeln, da meine Controls an die alte Objektliste aber nicht an die Sicherheitskopie gebunden sind. Wieder muss ich Code schreiben, um das in den Griff zu bekommen. Aber Linq und die abstrakte Modellierung sind so toll, dass ich das jetzt mal noch durchgehen lasse.</p>
<p>Dass der ObjectContext den RowState-Job übernommen hat, wäre ja okay. Aber was passiert, wenn ich dahin gehe, wo ich den ObjectContext nicht mitnehmen kann? Wenn ich Resultsets über Prozess- oder gar Maschinengrenzen hinweg übertragen muss? Ich denke da z.B. an eine verteilte Anwendung mit schönen, neuen, tollen WCF-Diensten. Aber auch da kann ich erstmal aufatmen, denn der ObjectContext kann auch loslassen. Objekte können nämlich vom Kontext "detached" (getrennet) und "attached" (angefügt) werden. Die Vorgehensweise ist damit - auf den Ersten Blick - ähnlich wie bei meinen ADO.NET-DataSets:</p>
<ul>
<li>
<div>WCF-Dienstseitig Daten von Datenquelle abrufen (Als Objektliste)</div></li>
<li>
<div>Objektliste detachen</div></li>
<li>
<div>Objektliste serialisieren und zum Client überragen</div></li>
<li>
<div>Auf dem Client mit den Objekten arbeiten</div></li>
<li>
<div>Ggf. geänderte Objektliste serialisieren und zurück zum Server übertragen, um die Änderungen zu persistieren</div></li>
<li>
<div>Ojektliste attachen</div></li>
<li>
<div>Änderungen Persistieren</div></li></ul>
<p>Klingt gut, nicht? Aber leider nur in der Theorie. Was passiert denn, wenn ich auf meinem Client eine Zeile in einem DataGridView lösche, welches an die Objektliste gebunden ist, die ich vorher vom WCF-Dienst abgerufen habe? Ganz klar, das DataBinding entfernt das Objekt aus der Auflistung. Nur ist diesmal kein ObjectContext da, der Protokoll führt. Angenommen mein DataGridView zeigt gerade zehn Zeilen an und ich lösche davon drei. Anschließend klicke ich auf Speichern. Wie soll der Server aber nun wissen, welche Datensätze er in der Datenbank löschen muss? Der ObjectContext weiss es nicht, da die betroffene Objektliste zum Löschzeitpunkt detatched war und außerdem auf einem ganz anderen Computer gelaufen ist. Ups! Jetzt fängt es an weh zu tun, denn ich muss mich auf dem Client selber darum kümmern, dass ausstehende Löschungen protokolliert werden. Außerdem muss das selbstgebastelte Löschprotokoll auch noch an den Server geschickt werden. Und zwar zusammen im selben Dienstaufruf, der auch neue und geänderte Datensätze persistiert, denn ich muss ja möglicherweise serverseitig eine Transaktion aufspannen. Die Persistenz-Odysee ist aber nocht nicht vorbei. Wenn die geänderte Objektliste und ggf. das Löschprotokoll wieder beim WCF-Dienst angekommen sind, muss die Objektliste zuerst wieder am ObjectContext attached werden. Dabei generiert der Kontext das Protokoll der Änderungen quasi nachträglich. Allerdings kann auch der ObjectContext die fehlenden RowState-Informationen nicht aus dem Ärmel schütteln. Er braucht dazu entweder eine Sicherheitskopie der ursprünglichen Objektliste oder er schaut in der Datenbank nach (will heißen, die Daten alle nochmal aus der Datenbank abrufen und vergleichen). Gelöschte erkennt er beim Attachen nur, wenn man eine Sicherheitskopie angibt. Ansonsten selbstgebasteltes Löschprotokoll mit Schleife durchgehen und für jeden DeleteObject aufrufen. </p>
<p>Ich finde, da machen die "fetten" typisierten DataSets von ADO.NET eine ganz gute Figur neben den hochgelobten schlanken Objekten. Wenn ich zusätzliche DB-Roundtrips bzw. Netzwerklast für Sichungskopien der Objektlisten im Ursprungszustand mitzähle, ist an OR-Mapping nichts schlankes mehr zu erkennen. Nur wesentlich mehr Arbeit und auch noch weniger Komfort beim clientseitigen Databinding.</p>
<p>Aber auch Typisierte DataSets sind nicht immer die Guten. Wenn es z.B. um Interoperabilität geht, fallen sie sofort durch. Ein Java-Client, der z.B. via SOAP auf einen WCF-Service zugreift, wird wenig Freude haben, wenn er ein DataSet deserialisieren soll. Leider enthält auch die XML-Serialisierung von DataSets .NET spezifische Inhalte. Auch Unabhängigkeit der DAL-Implementierung von einem bestimmten RDBMS ist mit normalem ADO.NET fast komplett Handarbeit (Und zwar wesentlich mehr, als ein bischen Detach- und Attach-Aufwand). Da macht die abstrakte Modellierung der DAL mit dem Entity Framework mehr Spaß. Es schreibt auch nicht jeder verteilte Anwendungen. Bei eine Standard-ASP.NET-Lösung ist es z.B. überhaupt nicht nötig Objektlisten zu detachen.</p>
<p>Am Ende kommt es auf das konkrete Projekt und dessen Umgebung an, welche Technologie sinnvoller ist. </p><img src="http://brightyellow.de/aggbug.aspx?PostID=56" width="1" height="1">Rainbirdhttp://brightyellow.de/members/Rainbird.aspxVisual Studio 2008 macht TableAdapter für n-Tier-Anwendungen salonfähighttp://brightyellow.de/blogs/rainbird/archive/2009/01/09/visual-studio-2008-macht-tableadapter-f-252-r-n-tier-anwendungen-salonf-228-hig.aspx2009-01-09T20:32:00Z2009-01-09T20:32:00Z<p>Der Beitrag kommt zwar etwas spät, aber besser als nie. <img src="http://yellow-rainbird.de/emoticons/emotion-5.gif" alt="Wink" /></p>
<p>Ich hatte mich vor einiger Zeit mal über TableAdapter ausgelassen (<a class="" title="Boese TableAdapter" href="http://yellow-rainbird.de/blogs/rainbird/archive/2008/03/18/ich-m-246-chte-f-252-r-typisierte-datasets-eine-lanze-brechen.aspx">hier nochmal zum Nachlesen</a>). Das Problem von TableAdaptern ist, dass sie scheinbar untrennbar mit dem DataSet verwurstelt sind. Datenstrukturen und die Datenzugriffslogik müssen bei einer n-Tier-Anwendung aber voneinander getrennt sein. Spätestens in verteilten Lösungen sind TableAdapter deshalb bis einschließlich Visual Studio 2005 nicht zu gebrauchen.</p>
<p>Neben all den hochtrabenden neuen Datentechnologieen (LINQ, Entity Framework ...) die das (mittlerweile nicht mehr ganz) neue Visual Studio 2008 mitbringt, haben die Meisten ein kleines aber feines Feature übersehen. Im DataSet-Designer ist es nämlich seit Visual Studio 2008 möglich, die eigentliche DataSet-Definition in ein anderes Visual Studio-Projekt der selben Projekmappe auszulagern. Der Designer-Part und die TableAdapter verbleiben dabei im ursprünglichen Projekt. Es wird sozusagen nur die "Schnittstelle" ausgelagert. Dazu muss man das Projekt, welches die DataSet-Klassen aufnehmen soll einfach auswählen (<em>Siehe folgender Screenshot; Klicken zum vergößern</em>).</p>
<p><a class="" href="http://yellow-rainbird.de/photos/allgemein/images/54/original.aspx"><img style="WIDTH:514px;HEIGHT:359px;" height="717" alt="n-Tier DataSet" src="http://yellow-rainbird.de/photos/allgemein/images/54/original.aspx" width="981" border="0" /></a></p>
<p>Die MSDN Library spricht von n-Tier-DataSets und n-Tier-Datenanwendungen. Ausführliche Infos und How-To´s gibts hier: <a href="http://msdn.microsoft.com/de-de/library/bb384587.aspx">http://msdn.microsoft.com/de-de/library/bb384587.aspx</a><br />DataSet-Designer und TableAdapter sind seit Visual Studio 2008 nun auch für Leute interessant, die keine Spaghetti-Code-Anwendungen schreiben. Ab sofort sind deshalb auch TableAdapter cool <img src="http://yellow-rainbird.de/emoticons/emotion-21.gif" alt="Yes" /><img src="http://yellow-rainbird.de/emoticons/emotion-11.gif" alt="Cool" />.</p>
<p><strong>Es ist beruhigend, dass auch bestehende Technologieen ab und zu mal etwas Pflege erfahren, statt den Hypes zu huldigen!</strong></p><img src="http://brightyellow.de/aggbug.aspx?PostID=53" width="1" height="1">Rainbirdhttp://brightyellow.de/members/Rainbird.aspxDienste einer n-Tier Anwendung in eine klare Hierarchie bringenhttp://brightyellow.de/blogs/rainbird/archive/2008/11/11/dienste-einer-n-tier-anwendung-in-eine-klare-hierarchie-bringen.aspx2008-11-11T20:23:00Z2008-11-11T20:23:00Z<p>Auf der guide to C# Live! Winter Edition hatten wir einige Diskussionen über die Architektur von Business<br />Anwendungen (<em>Ganz ähnlich übrigens auch auf mycsharp.de in folgendem Beitrag:<br /></em><a href="http://www.mycsharp.de/wbb2/thread.php?threadid=61812"><em>http://www.mycsharp.de/wbb2/thread.php?threadid=61812</em></a>). Den von mir vorgestellte Ansatz, die einzelnen <br />Dienste in Kategorieen einzuteilen und diese in einer Hierarchie anzuordnen, war manchen nicht ganz <br />verständlich gewesen. Der Bitte, das Ganze doch mal aufzuzeichnen, bin ich nun nachgekommen.<br />Folgende Skizze kann hoffentlich Abhilfe schaffen und helfen, den Ansatz besser zu verstehen:</p>
<p><img height="552" alt="Skizze hierarchischer Geschäftsdienste" src="http://yellow-rainbird.de/photos/allgemein/images/51/original.aspx" width="640" border="0" /></p>
<p><em>Eine Dienste haben gar keine Pfeilspitzen abbekommen. Das liegt daran, dass in der Skizze keine Clients <br />und auch keine Stapelverarbeitungsdienste (z.B. Rechnungsdruck) enthalten sind.</em> <br /> <br />Man kann sehr schön sehen, wie viele Abhängigkeiten es zwangsläufig gibt. Die Hierarchie gibt vor, dass<br />Dienste nur andere Dienste konsumieren dürfen, wenn diese über ihnen angebordnet sind. Niemals dürfen<br />Dienste andere Dienste konsumieren, die darunter oder auf gleicher Ebene angeordnet sind.<br />Diese Hierarchie muss allerdings vom Entwickler-Team auch so eingehalten werden. Es ist ein Konzept<br />bzw. eine Konvention. In einem drei bis vier Mann Team habe ich sehr gute Erfahrungen mit diesem Modell<br />gemacht. In größeren Teams ist da, denke ich, die Qualitätssicherungs-Abteilung gefordert. Damit alle auch <br />nach der Selben Hierarchie entwickeln, sollte diese unbedingt Dokumentiert werden (z.B. wie oben). <br /> <br />Ein Aspekt ist auf der Skizze allerings nicht abgebildet. Und zwar die Kommunikation nach außen. Wenn<br />ein Dienst externe Dienste (also z.B. einer Fremd-Applikation) konsumieren soll, muss dies immer entkoppelt<br />passieren. Das größe Problem dabei ist, Dinge wie Mandantenverwaltung, Sitzungen, Sicherheit und Locking<br />mit der externen Anwendung auf einen Nenner zu bekommen. Portal-Adapter-Paarungen zwischen internem <br />und externem Dienst können dabei für die Entkopplung und ggf. erforderliches Schnittstellen-Mapping sorgen.<br />Ein generischer Weg wäre z.B. der BizTalk Server.<br /> <br />Wenn man SOA ernsthaft umsetzen möchte, muss es sogar so sein, dass alle Dienste theoretisch <br />austauschbar sind. Das würde bedeuten, dass jeder Dienst auch eigene Kontrakte für alles, was er konsumiert. <br />Ohne Bus-System geht dann natürlich nichts mehr. Der Entwicklungs- und Testaufwand vervielfacht sich, <br />wenn die komplette Kommunikation über ein Bus-System laufen soll.<br /> <br />Aber auch ohne Bus-System bringt der Hierarchische-Ansatz eine Menge. Die Abhängigkeiten werden auf ein<br />Mindestmaß reduziert und folgen klaren Regeln. Dienste lassen sich gut testen, da man für einen Test den <br />Zugriff auf höher liegende Dienste auch auf einen Dummy-Dienst umleiten kann. Die Lösung ist in sich klar<br />strukturiert und die Kommunikation zwischen den Diensten funktioniert über explizite Schnittstellen. Die<br />Entwicklungsarbeit im Team lässt sich gut Aufteilen und parallele Entwicklung von Diensten ist - insofern<br />man Contract-First durchzieht - auch kein Problem. Die Entwicklung solcher Dienste ist einfach und nicht an<br />komplexe Container-Modelle oder Vererbungsbäume gebunden. Die Einarbeitungszweit für neue Entwickler ist<br />minimal - vorausgesetzt die Infrastrukturdienste (oben gelb dargestellt) stehen schon und es wurde eine intuitive <br />API für die Infrastruktur geschaffen (z.B. generischen Service-Locator, Microkernel, Statische Hilfsklasse für<br />den Sicherheitsdienst und das Locking). </p><img src="http://brightyellow.de/aggbug.aspx?PostID=52" width="1" height="1">Rainbirdhttp://brightyellow.de/members/Rainbird.aspxguide to C# Live! Winter Edition 2008http://brightyellow.de/blogs/rainbird/archive/2008/11/11/guide-to-c-live-winter-edition-2008.aspx2008-11-11T20:00:00Z2008-11-11T20:00:00Z<p><a class="" href="http://www.guidetocsharplive.de/"><img height="151" alt="Logo guide to C Sharp Live" src="http://yellow-rainbird.de/photos/allgemein/images/48/original.aspx" width="363" border="0" /></a></p>
<p>Ich war da! Es war eine tolle Veranstaltung. Golo hat den Teilnehmern <br />in den drei Tagen die Themen Software-Architektur, LINQ und WPF<br />näher gebracht. Statt vieler Folien und langen Monologen, hat der<br /><a class="" href="http://www.des-eisbaeren-blog.de/">Eisbär</a> auf Dynamik am Flipchart und viel Interaktion mit den <br />Teilnehmern gesetzt. Deshalb war die Veranstaltung alles andere<br />als langweilig. </p>
<p>Am zweiten Tag habe ich noch einen kleinen Beitrag zum Thema<br /><a class="" href="http://msdn.microsoft.com/de-de/library/ms735119.aspx">Windows Communication Foundation</a> beigesteuert. Den Quellcode<br />meiner zwei kleinen WCF-Demos (<em>und der net.tcp-Versionen, die<br />beim live Codieren leider nicht auf anhieb geklappt hatte</em>) gibts<br />hier zum runterladen: </p>
<p><a href="http://yellow-rainbird.de/files/folders/quellcode/entry49.aspx">http://yellow-rainbird.de/files/folders/quellcode/entry49.aspx</a></p>
<p>Viel Spaß damit!</p><img src="http://brightyellow.de/aggbug.aspx?PostID=50" width="1" height="1">Rainbirdhttp://brightyellow.de/members/Rainbird.aspxmycsharp.de Community Treffenhttp://brightyellow.de/blogs/rainbird/archive/2008/08/27/mycsharp-de-community-treffen.aspx2008-08-27T06:04:00Z2008-08-27T06:04:00Z<p>Anlässlich des fünften Geburtstags von mycsharp.de findet am 30.08.2008 ein Community Treffen in Köln statt. Ich werde auf jeden Fall da sein und freue mich schon darauf, einige myCSharper leibhaftig kennen zu lernen.</p>
<p><a href="http://www.mycsharp.de/wbb2/thread.php?postid=329415#post329415">http://www.mycsharp.de/wbb2/thread.php?postid=329415#post329415</a></p>
<p> </p><img src="http://brightyellow.de/aggbug.aspx?PostID=46" width="1" height="1">Rainbirdhttp://brightyellow.de/members/Rainbird.aspxFun: Klassische 2D-Spiele erstellenhttp://brightyellow.de/blogs/rainbird/archive/2008/04/24/fun-klassische-2d-spiele-erstellen.aspx2008-04-23T23:39:00Z2008-04-23T23:39:00Z<p> <img height="685" alt="Bild1" src="http://yellow-rainbird.de/photos/allgemein/images/40/original.aspx" width="971" border="0" /></p>
<p>Wer schon immer mal klassische 2D-Rollenspiele in der Art von Zelda oder Final Fanatasy III machen wollte, ohne gleich ein C#-Megaprojekt zu starten, sollte sich mal den RPG Maker VX ansehen. Der RPG Maker ist ein Editor für 2D-Rollenspiele. Karten, Items und Monster lassen sich kinderleicht zuammenklicken. Wem das nicht reicht, kann mit Ruby Skripte schreiben oder auch die Game Engine direkt anpassen. Für alle Spielrelevanten Dinge wie z.B. Sprites bietet die API RGSS fertige Objekte an. Eine .NET Schnittstelle ist zwar nicht integriert, aber man kann Windows-API-Funktionen oder native C/C++ DLLs aufrufen.</p>
<p><a class="" title="www.rpgmaker-vk.com" href="http://www.rpgmaker-vx.com/">Herstellerseite des RPG Makers VX</a></p><img src="http://brightyellow.de/aggbug.aspx?PostID=41" width="1" height="1">Rainbirdhttp://brightyellow.de/members/Rainbird.aspxDie neue erweiterte Version meines n-Tier Architekturbeispiels ist da!http://brightyellow.de/blogs/rainbird/archive/2008/04/12/die-neue-erweiterte-version-meines-n-tier-architekturbeispiels-ist-da.aspx2008-04-11T22:53:00Z2008-04-11T22:53:00Z<p>Endlich ist es soweit. Ich habe die Zeit gefunden, das Beispiel im ursprünglich geplanten Umfang fertigzustellen. <br />Das Ergebnis gibts im Download-Bereich von yellow-rainbird.de und auf <a href="http://www.mycsharp.de/">www.mycsharp.de</a> kostenfrei zum runterladen.</p>
<p><a class="" title="n-Tier Architekturbeispiel Version 1.1.0.0" href="http://www.mycsharp.de/wbb2/thread.php?postid=291674#post291674">Jetzt herunterladen</a></p>
<p>Als kleines Zusatzfeature kann man nun auch die Oberflächensprache zur Laufzeit ändern. Dies zeigt auch, wie einfach man mit dem .NET Framework Anwendungen lokalisieren kann.</p>
<p><img height="246" alt="Screenshot" src="http://yellow-rainbird.de/photos/allgemein/images/37/original.aspx" width="570" border="0" /></p><img src="http://brightyellow.de/aggbug.aspx?PostID=38" width="1" height="1">Rainbirdhttp://brightyellow.de/members/Rainbird.aspxLagermodul für Architekturbeispiel Rainbird.Examples.NTier fast fertighttp://brightyellow.de/blogs/rainbird/archive/2008/03/19/lagermodul-f-252-r-architekturbeispiel-rainbird-examples-ntier-fast-fertig.aspx2008-03-19T00:12:00Z2008-03-19T00:12:00Z<p>Das zweite Modul mit dem Namen Lageverwaltung für mein kleines n-Tier-Architekturbeispiel ist fast fertig und wird in Kürze hier und auf <a class="" title="myCSharp.de - Gemeinsam mehr erreichen" href="http://www.mycsharp.de/">mycsharp.de</a> veröffentlicht. Einen ersten Screenshot davon gibts hier: <a class="" title="Screenshot" href="http://yellow-rainbird.de/photos/allgemein/images/28/original.aspx">Screenshot</a>. </p>
<p> </p><img src="http://brightyellow.de/aggbug.aspx?PostID=29" width="1" height="1">Rainbirdhttp://brightyellow.de/members/Rainbird.aspxIch möchte für Typisierte DataSets eine Lanze brechenhttp://brightyellow.de/blogs/rainbird/archive/2008/03/18/ich-m-246-chte-f-252-r-typisierte-datasets-eine-lanze-brechen.aspx2008-03-18T21:37:00Z2008-03-18T21:37:00Z<p>Ich höre immer wieder Leute sagen, Typisierte DataSets seien böse. Im Jahre 2003 wollte ich davon auch noch nichts wissen. Aber Typisierte DataSets, wie sie Visual Studio 2005 erzeugt sind eine feine Sache. Ich habe mich deshalb gefragt, warum Typisierte DataSets so verteufelt werden?</p>
<p>Höchstwahrscheinlich ist der DataSet-Designer von Visual Studio schuld. Wenn man als fauler Designer-Fan eine SQL Server Tabelle aus dem Server-Explorer per Drag&Drop in den DataSet-Designer zieht, passiert das hier:</p>
<p><img height="591" alt="Screenshot" src="http://yellow-rainbird.de/photos/allgemein/images/26/original.aspx" width="630" border="0" /></p>
<p>Der Designer erstellt zwar automatisch eine schöne DataTable im DataSet, die alle Spalten der SQL Server Tabelle enthält, aber er hängt unten etwas dran (<em>Fokus des bedrohlichen roten Wirbels im Bild</em>). Es ist ein sogenannter TableAdapter. Zweck eines TableAdapters ist es, die DataTable, an der er hängt, mit Daten aus einer Datenbank zu füllen und Änderungen an der DataTable in einer Datenbank zu persistieren. Ein DataSet bzw. eine DataTable ist ein Container-Objekt, welches verwendet wird, um strukturierte Daten zwischen Komponenten auszutauschen. Man kann auch sagen ein DataSet ist eine Datenstruktur. So ein Container sollte passiv sein. Das heißt er sollte von "außen" befüllt werden und sich nicht selbts füllen. Der TableAdapter macht genau das Gegenteil. Er verwandelt das DataSet selbst in eine aktive Komponente. Und damit nicht genug. Ein Datenbankzugriff benötigt natürlich immer eine Verbindungszeichenfolge. Die hat der Designer heimlich, still und leise nebenbei als Anwendungseinstellung angelegt. So bekommt das Visual Studio-Projekt indem das DataSet liegt, plötzlich und automatisch eine Anwendungskonfigurationsdatei (<strong>App.config</strong>) untergeschoben:</p><font color="#0000ff" size="2">
<p><font face="courier new,courier"><?</font></font><font face="courier new,courier"><font color="#a31515" size="2">xml</font><font color="#0000ff" size="2"> </font><font color="#ff0000" size="2">version</font><font color="#0000ff" size="2">=</font><font size="2">"</font><font color="#0000ff" size="2">1.0</font><font size="2">"</font><font color="#0000ff" size="2"> </font><font color="#ff0000" size="2">encoding</font><font color="#0000ff" size="2">=</font><font size="2">"</font><font color="#0000ff" size="2">utf-8</font><font size="2">"</font></font><font face="courier new,courier"><font color="#0000ff" size="2"> ?><br /><</font><font color="#a31515" size="2">configuration</font></font><font face="courier new,courier"><font color="#0000ff" size="2">><br /> <</font><font color="#a31515" size="2">configSections</font></font><font face="courier new,courier"><font color="#0000ff" size="2">><br /></font><font color="#0000ff" size="2"> </</font><font color="#a31515" size="2">configSections</font></font><font face="courier new,courier"><font color="#0000ff" size="2">><br /> <</font><font color="#a31515" size="2">connectionStrings</font></font><font face="courier new,courier"><font color="#0000ff" size="2">><br /> <</font><font color="#a31515" size="2">add</font><font color="#0000ff" size="2"> </font><font color="#ff0000" size="2">name</font><font color="#0000ff" size="2">=</font><font size="2">"</font><font color="#0000ff" size="2">WindowsApplication2.Properties.Settings.NTierExampleConnectionString</font><font size="2">" <br /> </font><font color="#ff0000" size="2">connectionString</font><font color="#0000ff" size="2">=</font><font size="2">"</font><font color="#0000ff" size="2">Data Source=AMILO;Initial Catalog=NTierExample;Integrated Security=True</font><font size="2">" <br /> </font><font color="#ff0000" size="2">providerName</font><font color="#0000ff" size="2">=</font><font size="2">"</font><font color="#0000ff" size="2">System.Data.SqlClient</font><font size="2">"</font></font><font face="courier new,courier"><font color="#0000ff" size="2"> /><br /> </</font><font color="#a31515" size="2">connectionStrings</font></font><font face="courier new,courier"><font color="#0000ff" size="2">><br /></</font><font color="#a31515" size="2">configuration</font><font color="#0000ff" size="2">></font></font></p>
<p><font color="#0000ff"><font color="#000000" size="2">Spätestens jetzt haben bestimmt viele auf das kleine X rechts oben geklickt und sich nach einem OR-Mapping Werkzeug umgesehen. </font></font></p>
<p><font color="#0000ff"><font color="#000000" size="2">Wenn der TableAdapter der Böse ist, liegt es klar auf Hand, was zu tun ist, um sinnvoll mit Typisierten DataSets arbeiten zu können. <img src="http://yellow-rainbird.de/emoticons/emotion-55.gif" alt="Idea" /> Richtig, kein Drag&Drop aus dem Server-Explorer! Stattdessen Tabellen, Spalten, Schlüssel und Beziehungen manuell im DataSet-Designer zusammenklicken. Das ist etwas mehr Arbeit, aber man erhält hinterher ein sauberes DataSet, welches von keiner Datenquelle abhängig ist. </font></font><font color="#0000ff"><font color="#000000" size="2">Füllen und Persistieren des DataSets kann so eine eigenständige Geschäftskomponente übernehmen. Dem DataSet ist es egal, von welcher Datenbank die Daten kommen und wohin Änderungen persistiert werden.</font></font></p>
<p><img height="310" alt="Screenshot" src="http://yellow-rainbird.de/photos/allgemein/images/27/original.aspx" width="481" border="0" /></p>
<p><font color="#0000ff"><font color="#000000" size="2">Es gibt noch einen Grund, warum DataSets im allgemeinen verpöhnt sind. Scheinbar denken viele Leute, Typisierte DataSets müsse man immer als Ganzes einsetzen. Also in etwa so:</font></font></p><font color="#0000ff"><font color="#000000" size="2"><font color="#008000" size="2">
<p><font face="courier new,courier">// Neues Produkt Management-DataSet erzeugen<br /></font></font><font face="courier new,courier"><font color="#2b91af" size="2">ProductManagementDataSet</font><font size="2"> dataContainer = </font><font color="#0000ff" size="2">new</font><font size="2"> </font><font color="#2b91af" size="2">ProductManagementDataSet</font><font size="2">();</p></font></font></font></font>
<p><font color="#0000ff"><font color="#000000" size="2">Oft braucht man aber nur eine Tabelle und nicht drei auf eimal. Auch Beziehungen um zwischen Eltern- und Kind-Datensätzen zu springen, werden eher selten benötigt. Trotzdem arbeiten die meisten Tutorials, Bücher und Beispiele zu ADO.NET und DataSets immer mit ganzen DataSets. Dabei sind DataTables eigenständige Objekte, die auch dann alleine leben können, wenn sie in einem Typisierten DataSet definiert wurden. Wenn ich z.B. nur mit Produkten arbeiten will, mich aber Kategorieen und Preise gerade nicht interessieren, verwende ich auch nur die entsprechende DataTable und nicht das ganze DataSet:</font></font></p><font color="#0000ff"><font color="#000000" size="2"><font color="#008000" size="2">
<p><font face="courier new,courier">// Neue Produkt-Tabelleninstanz erzeugen<br /></font></font><font face="courier new,courier"><font color="#2b91af" size="2">ProductManagementDataSet</font><font size="2">.</font><font color="#2b91af" size="2">ProductsDataTable</font><font size="2"> dataContainer = </font><font color="#0000ff" size="2">new</font><font size="2"> </font><font color="#2b91af" size="2">ProductManagementDataSet</font><font size="2">.</font><font color="#2b91af" size="2">ProductsDataTable</font><font size="2">();</p></font></font></font></font>
<p><font color="#0000ff"><font color="#000000" size="2">Jetzt beginnt das Argument "DataSets haben zu viel Overhead und sind unhandlich!" zu bröckeln. Ich neige dazu für jeden Bereich einer Geschäftsanwendung ein Typisiertes DataSet zu erstellen, welches die Datenstrukturen für diesen Bereich enthält. Diese DataSets werden in separate Assemblies gelegt. So können verschiedene Komponenten und Prozesse mit den selben Datenstrukturen arbeiten. Alles ist typsicher und hat den vollen Komfort von DataSets/DataTables.</font></font></p>
<p><font size="2">Da Typisierte DataSets von System.Data.DataSet und deren Tabellen von System.Data.DataTable abgleitet sind, kann man mit Typisierten DataSet alles machen, was man mit den Basisklassen auch machen kann (<em>z.B. DataView darauf anwenden, Filtern, Suchen, Zusammenführen, etc</em>.). </font><font color="#0000ff"><font color="#000000">Was den Komfort angeht, sind DataSets/DataTables unschlagbar (<em>Ich lasse mich natürlich gerne vom Gegenteil überzeugen</em>)!</font></font></p>
<p><font color="#0000ff"><font color="#000000">Wer Typisierten DataSets trotzdem noch nicht über den Weg traut, dem möchte ich gerne folgendes Architekturbeispiel von mir ans Herz legen: <a class="" title=".NET Applikationsserver auf mycsharp.de" href="http://www.mycsharp.de/wbb2/thread.php?threadid=48592" target="_blank">.NET Applikationsserver auf mycsharp.de</a>. In diesem kleinen Projekt werden DataSets als Datentransfer-Objekte eingesetzt, die strukturierte Daten zwischen einem kleinen Applikationsserver und einem Windows.Forms-Client übertragen.</font></font></p>
<p><font color="#0000ff"><font color="#000000"><strong><u>Fazit:</u></strong></font></font></p>
<p><font color="#0000ff"><font color="#000000">Typisierte DataSets sind cool.<img src="http://yellow-rainbird.de/emoticons/emotion-11.gif" alt="Cool" /><br />Typisierte DataTables sind cool.<img src="http://yellow-rainbird.de/emoticons/emotion-11.gif" alt="Cool" /><br />TableAdapter sind böse <img src="http://yellow-rainbird.de/emoticons/emotion-60.gif" alt="Lightning" /> und damit der eigentliche Teufel <img src="http://yellow-rainbird.de/emoticons/emotion-14.gif" alt="Devil" />, den man austreiben sollte.</font></p></font><img src="http://brightyellow.de/aggbug.aspx?PostID=25" width="1" height="1">Rainbirdhttp://brightyellow.de/members/Rainbird.aspxDiagnosewerkzeug für VSTO Deployment-Problemehttp://brightyellow.de/blogs/rainbird/archive/2008/03/18/diagnosewerkzeug-f-252-r-vsto-deployment-probleme.aspx2008-03-18T20:23:00Z2008-03-18T20:23:00Z<p>Ich bin heute ziemlich lange an einem Problem mit einem <a class="" title="VSTO" href="http://yellow-rainbird.de/forums/p/22/24.aspx#24" target="_blank">VSTO</a> Word Add-In gesessen. Trotz korrket installierter <a class="" title="VSTO" href="http://yellow-rainbird.de/forums/p/22/24.aspx#24" target="_blank">VSTO</a> 2005 SE Runtime und Primary Interop Assemblies für Office 2003 wollte das Word Add-In einfach nicht laufen. Ein anderes <a class="" title="VSTO" href="http://yellow-rainbird.de/forums/p/22/24.aspx#24" target="_blank">VSTO</a> Add-In in Outlook hingegen lief ohne Probleme.</p>
<p>Nach langer Suche in TechNet und MSDN habe ich irgendwann ein kleines Werkzeug mit dem schönen Namen <a class="" title="Microsoft PSS VSTO 2005 Client TroubleShooter" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c9fb6a54-8069-4918-a6f9-e744928dfac3&DisplayLang=en" target="_blank">Microsoft PSS VSTO 2005 Client TroubleShooter</a> gefunden. Der TroubleShooter prüft, ob alle DLLs, die <a class="" title="VSTO" href="http://yellow-rainbird.de/forums/p/22/24.aspx#24" target="_blank">VSTO</a> Add-Ins benötigen in der richtigen Version installiert sind und zeigt das Ganze in einer übersichtlichen Liste an. Zusätzlich werden noch bestimmte Einstellungen aufgeführt.</p>
<p><img height="1" alt="" src="http://yellow-rainbird.de/photos/allgemein/images/23/original.aspx" width="1" border="0" /><img height="480" alt="Screenshot" src="http://yellow-rainbird.de/photos/allgemein/images/23/original.aspx" width="570" border="0" /></p>
<p>In meinem Fall hatte Word eine Datei mit dem Namen <font face="courier new,courier">_msaccess.exe.config</font> als Konifurationsdatei für das VSTO Add-In herangezogen. Das war eine ziemlich alte Konfigurationsdatei, die ich einmal für ein .NET 1.1 Assembly angelegt hatte, die via COM-Interop von Microsoft Access aufgerufen worden war. Die Konfiguration hatte damals die Verwendung von .NET Framework Version 1.1 erzwungen. Bei Access hatte der vorangestellte Unterstrich erfolgreich verhindert, dass die CLR diese Datei als Konfigurationsdatei verwendet. Dass Word diese Datei automatisch angezogen hat, verwundert mich sehr. Ich hätte es verstanden, wenn die Datei winword.exe.config geheißen hätte. </p>
<p>Der TroubleShooter hatte die alte Anwendungs-Konfigurationsdatei in seiner Liste aufgeführt und mich so auf die Fehlerursache aufmerksam gemacht. Nach dem löschen der <font face="Courier New">_msaccess.exe.config</font> hatte das <a class="" title="VSTO" href="http://yellow-rainbird.de/forums/p/22/24.aspx#24" target="_blank">VSTO</a> Word Add-In sofort funktioniert. </p>
<p>Da <a class="" title="VSTO" href="http://yellow-rainbird.de/forums/p/22/24.aspx#24" target="_blank">VSTO</a> Add-Ins nicht sagen, wenn ihnen irgendwas wehtut, sondern einfach garnichts machen, sollte man vor dem Ausrollen eines Add-Ins auf Produktiv-Maschinen den TroubleShooter zur Hand nehmen und überprüfen, ob die Konfiguration und die installierten Pakete in Ordnung sind. </p><img src="http://brightyellow.de/aggbug.aspx?PostID=22" width="1" height="1">Rainbirdhttp://brightyellow.de/members/Rainbird.aspxRainbird´s Bloghttp://brightyellow.de/blogs/rainbird/archive/2008/03/10/rainbird-180-s-blog.aspx2008-03-10T05:49:00Z2008-03-10T05:49:00Z<p>Es ist soweit! Ich gehe nun auch unter die Blogger.<br />Mein Blog ist hauptsächlich dem Thema Softwareentwicklung mit dem .NET Framework gewidmet.</p>
<p>Natürlich sieht jetzt alles noch etwas kahl aus, aber das wird sich bald ändern.<br />Für die Zukunft wünsche ich viel Spaß beim lesen.</p>
<p>Ich freue mich immer über Feedback zu meinem Blog oder zu yellow-rainbird.de allgemein. <br />Fragen, Meinungen oder konstruktive Kritik bitte per E-Mail an <a href="mailto:hagen.siegel@the-rainbird.de">hagen.siegel@the-rainbird.de</a> senden.</p>
<p><em>Rainbird</em></p><img src="http://brightyellow.de/aggbug.aspx?PostID=16" width="1" height="1">Rainbirdhttp://brightyellow.de/members/Rainbird.aspx