<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>build broken &#187; Thomas Christian</title>
	<atom:link href="http://blog.aztec-project.org/author/tch/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.aztec-project.org</link>
	<description>but we can fix it! Sometimes :)</description>
	<lastBuildDate>Fri, 11 Jun 2010 12:52:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Asynchrone Kommunikation mit dem Async-Pattern (Refactored)</title>
		<link>http://blog.aztec-project.org/2010/05/06/asynchrone-kommunikation-mit-dem-async-pattern-refactored/</link>
		<comments>http://blog.aztec-project.org/2010/05/06/asynchrone-kommunikation-mit-dem-async-pattern-refactored/#comments</comments>
		<pubDate>Thu, 06 May 2010 12:37:46 +0000</pubDate>
		<dc:creator>Thomas Christian</dc:creator>
				<category><![CDATA[Architektur]]></category>
		<category><![CDATA[Pattern]]></category>
		<category><![CDATA[Tipps]]></category>

		<guid isPermaLink="false">http://blog.aztec-project.org/?p=1027</guid>
		<description><![CDATA[Nach dem ich meinen vorherigen Artikel zum Thema &#8220;Asynchrone Kommunikation mit dem Async-Pattern&#8221; vorgestellt hatte, hat Ralf Westphal auf seinem Blog &#8220;One Man Think Tank Gedanken&#8221; das Vorgehen zur Implementierung einer asynchronen Kommunikation mit Hilfe von Event-Based-Components vorgestellt, welches eine sehr gute Alternative zum Async-Pattern ist. Seinen Eintrag nehme ich zum Anlass, um meine Beispiel-Implementierung [...]]]></description>
			<content:encoded><![CDATA[<p>Nach dem ich meinen vorherigen Artikel zum Thema <a href="http://blog.aztec-project.org/2010/05/05/asynchrone-kommunikation-mit-dem-async-pattern/">&#8220;Asynchrone Kommunikation mit dem Async-Pattern&#8221;</a> vorgestellt hatte, hat Ralf Westphal auf seinem Blog <a href="http://ralfw.blogspot.com/2010/05/asynchrone-kommunikation-mit-ebcs-statt.html">&#8220;One Man Think Tank Gedanken&#8221;</a> das Vorgehen zur Implementierung einer asynchronen Kommunikation mit Hilfe von Event-Based-Components vorgestellt, welches eine sehr gute Alternative zum Async-Pattern ist. Seinen Eintrag nehme ich zum Anlass, um meine Beispiel-Implementierung des Async-Pattern zu refaktorisieren, um eine bessere Trennung der Verantwortlichkeiten und somit eine bessere Lesbarkeit zu erreichen.</p>
<p>In das Form wird die Abhängigkeit &#8220;CalcProxy&#8221; injected.</p>
<style type="text/css">
.cf { font-family: Courier New; font-size: 10pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: #2b91af; }
</style>
<div class="cf">
<p class="cl"><span class="cb1">static</span> <span class="cb1">void</span> Main()</p>
<p class="cl">{</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb2">CalcProxy</span> calcProxy = <span class="cb1">new</span> <span class="cb2">CalcProxy</span>(<span class="cb1">new</span> <span class="cb2">Calculator</span>());</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb2">Application</span>.EnableVisualStyles();</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb2">Application</span>.SetCompatibleTextRenderingDefault(<span class="cb1">false</span>);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb2">Application</span>.Run(<span class="cb1">new</span> <span class="cb2">Form1</span>(calcProxy));</p>
<p class="cl">}</p>
</div>
<p>&nbsp;</p>
<p>Im Gegensatz zur vorherigen Version wird in der Form nun nicht mehr der Calculator direkt erzeugt und verwendet, sondern auf den injekteten CalcProxy zugegriffen.</p>
<style type="text/css">
.cf { font-family: Courier New; font-size: 10pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: #2b91af; }
</style>
<div class="cf">
<p class="cl"><span class="cb1">public</span> <span class="cb1">partial</span> <span class="cb1">class</span> <span class="cb2">Form1</span> : <span class="cb2">Form</span> {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">readonly</span> <span class="cb2">ICalcProxy</span> m_calcProxy;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> Form1(<span class="cb2">ICalcProxy</span> calcProxy) {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; InitializeComponent();</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; m_calcProxy = calcProxy;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; m_calcProxy.CalcCompleted += CalculatorCalcCompleted;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">void</span> Run_Click(<span class="cb1">object</span> sender, <span class="cb2">EventArgs</span> e) {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">int</span> number;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">if</span> (<span class="cb2">Int32</span>.TryParse(txbEingabe.Text, <span class="cb1">out</span> number)) {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; m_calcProxy.CalcAsync(number, number);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">void</span> CalculatorCalcCompleted(<span class="cb1">object</span> sender, <span class="cb2">CalcEventArgs</span> eventArgs) {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lblCounter.Text = eventArgs.UserState.ToString();</p>
<p class="cl">&nbsp;&nbsp;&nbsp; }</p>
<p class="cl">}</p>
</div>
<p>&nbsp;</p>
<p>Der CalcProxy wiederum bekommt die Abhängigkeit zum Calculator injected und stellt für die Calculator.Calc-Methode sowohl eine synchrone als auch eine asynchrone Methode zur Verfügung.</p>
<style type="text/css">
.cf { font-family: Courier New; font-size: 10pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: #2b91af; }
.cb3 { color: #a31515; }
</style>
<div class="cf">
<p class="cl"><span class="cb1">public</span> <span class="cb1">class</span> <span class="cb2">CalcProxy</span> : <span class="cb2">ICalcProxy</span> {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">readonly</span> <span class="cb2">ICalculator</span> m_calculator;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">event</span> <span class="cb2">CalcCompletedEventHandler</span> CalcCompleted;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb2">AsyncOperation</span> m_asyncOperation;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">bool</span> m_isRunning;</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> CalcProxy(<span class="cb2">ICalculator</span> calculator) {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; m_calculator = calculator;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">int</span> Calc(<span class="cb1">int</span> number) {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">return</span> m_calculator.Calc(number);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">void</span> CalcAsync(<span class="cb1">int</span> number, <span class="cb1">object</span> userState) {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">lock</span> (<span class="cb1">this</span>) {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">if</span> (m_isRunning) {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">throw</span> <span class="cb1">new</span> <span class="cb2">InvalidOperationException</span>(<span class="cb3">&quot;Diese Operation wird bereits ausgef&#252;hrt&quot;</span>);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; m_isRunning = <span class="cb1">true</span>;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; m_asyncOperation = <span class="cb2">AsyncOperationManager</span>.CreateOperation(userState);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">ThreadPool</span>.QueueUserWorkItem(ExecuteCalc, number);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">void</span> ExecuteCalc(<span class="cb1">object</span> state) {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">var</span> result = Calc((<span class="cb1">int</span>)state);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; m_asyncOperation.PostOperationCompleted(CalcCompletedSuccessful, result);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">private</span> <span class="cb1">void</span> CalcCompletedSuccessful(<span class="cb1">object</span> result) {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">if</span> (CalcCompleted != <span class="cb1">null</span>) {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CalcCompleted(<span class="cb1">this</span>, <span class="cb1">new</span> <span class="cb2">CalcEventArgs</span>(<span class="cb1">null</span>, <span class="cb1">false</span>, (<span class="cb1">int</span>)result, result));</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p class="cl">&nbsp;&nbsp;&nbsp; }</p>
<p class="cl">}</p>
</div>
<p>&nbsp;</p>
<p>Nun enthält der Calculator nur noch die Methode die für den Calculator notwendig ist, nämlich die Calc-Methode.</p>
<style type="text/css">
.cf { font-family: Courier New; font-size: 10pt; color: black; background: white; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: #2b91af; }
</style>
<div class="cf">
<p class="cl"><span class="cb1">public</span> <span class="cb1">class</span> <span class="cb2">Calculator</span> : <span class="cb2">ICalculator</span> {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; <span class="cb1">public</span> <span class="cb1">int</span> Calc(<span class="cb1">int</span> number) {</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb2">Thread</span>.Sleep(10000);</p>
<p class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="cb1">return</span> number * number;</p>
<p class="cl">&nbsp;&nbsp;&nbsp; }</p>
<p class="cl">}</p>
</div>
<p><a href="http://dotnet-kicks.de/kick/?url=http%3a%2f%2fblog.aztec-project.org%2f2010%2f05%2f06%2fasynchrone-kommunikation-mit-dem-async-pattern-refactored%2f"><img src="http://dotnet-kicks.de/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fblog.aztec-project.org%2f2010%2f05%2f06%2fasynchrone-kommunikation-mit-dem-async-pattern-refactored%2f" alt="kick it on dotnet-kicks.de" border="0"></a></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.aztec-project.org%2F2010%2F05%2F06%2Fasynchrone-kommunikation-mit-dem-async-pattern-refactored%2F&amp;title=Asynchrone%20Kommunikation%20mit%20dem%20Async-Pattern%20%28Refactored%29" id="wpa2a_2"><img src="http://blog.aztec-project.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.aztec-project.org/2010/05/06/asynchrone-kommunikation-mit-dem-async-pattern-refactored/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Asynchrone Kommunikation mit dem Async-Pattern</title>
		<link>http://blog.aztec-project.org/2010/05/05/asynchrone-kommunikation-mit-dem-async-pattern/</link>
		<comments>http://blog.aztec-project.org/2010/05/05/asynchrone-kommunikation-mit-dem-async-pattern/#comments</comments>
		<pubDate>Wed, 05 May 2010 14:52:17 +0000</pubDate>
		<dc:creator>Thomas Christian</dc:creator>
				<category><![CDATA[Architektur]]></category>
		<category><![CDATA[Pattern]]></category>
		<category><![CDATA[Tipps]]></category>

		<guid isPermaLink="false">http://blog.aztec-project.org/?p=961</guid>
		<description><![CDATA[Bevor ich anhand eines Beispiels zeige, wie man mit Hilfe des Async-Pattern ein asynchrone Kommunikation implementieren kann, möchte ich kurz beschreiben, wo der Unterschied zwischen der synchronen und der asynchronen Kommunikation liegt und wofür die asynchrone Kommunikation nützlich ist. Synchrone Kommunikation Bei der synchronen Kommunikation handelt es sich um eine Echtzeit-Kommunikation. Das bedeutet, dass Anfragen [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal" style="text-align: justify;">Bevor ich anhand eines Beispiels zeige, wie man mit Hilfe des Async-Pattern ein asynchrone Kommunikation implementieren kann, möchte ich kurz beschreiben, wo der Unterschied zwischen der synchronen und der asynchronen Kommunikation liegt und wofür die asynchrone Kommunikation nützlich ist.</p>
<p class="MsoListParagraphCxSpFirst" style="margin-left: 35.45pt; text-align: justify;">
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0cm; text-align: justify;"><strong><span style="font-size: 12pt; line-height: 115%;">Synchrone Kommunikation</span></strong></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0cm; text-align: justify;">Bei der synchronen Kommunikation handelt es sich um eine Echtzeit-Kommunikation. Das bedeutet, dass Anfragen und Antworten jeweils vollständig nacheinander abgearbeitet werden. Kommuniziert ein Prozess mit einem Webserver synchron, so ist der Prozess solange blockiert, bis er die vollständige Antwort vom Webserver erhalten hat.</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0cm; text-align: justify;">
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0cm; text-align: justify;"><strong><span style="font-size: 12pt; line-height: 115%;">Asynchrone Kommunikation</span></strong></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0cm; text-align: justify;">Im Gegensatz zur synchronen Kommunikation handelt es sich bei der asynchronen Kommunikation nicht um eine Echtzeit-Kommunikation. Das bedeutet, dass bei der Kommunikation eines Prozesses mit einem Webserver der Prozess nicht blockiert. Der Prozess verschickt lediglich die Anfrage an den Webserver und kehrt danach sofort zur weiteren Prozessausführung zurück. Der Prozess geht dabei davon aus, dass die Anfrage an den Webservice korrekt gestellt wurde. Die Antwort wird dann zu einem unbestimmten Zeitpunkt vom Webservice geliefert, und zwar dann, wenn dieser mit der Abarbeitung der Anfrage fertig ist.</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0cm; text-align: justify;">
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0cm; text-align: justify;"><strong><span style="font-size: 12pt; line-height: 115%;">Warum Asynchrone Kommunikation</span></strong></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0cm; text-align: justify;">Asynchrone Kommunikation bietet sich in unterschiedlichsten Situationen an. So ist es z.B. sinnvoll, dass eine WinForms-Anwendung asynchron mit einem Webservice kommuniziert, da der Haupt-Thread der WinForm-Anwendung sonst so lange blockiert wäre, bis der Webservice die Antwort auf die Anfrage liefert. Die Folge wäre, dass im Titel der Anwendung stehen würde, dass die Anwendung nicht antwortet (s. Abbildung 1). Viele Benutzer denken dass es sich bei dieser Meldung um einen Fehler im Programm handelt und beenden das Programm fix über den Task-Manager. Dabei lag es nur an der etwas länger dauernden Kommunikation zwischen der WinForm-Anwendung und dem Webservice.</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0cm; text-align: justify;">
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 35.45pt; text-align: center; page-break-after: avoid;"><span></span></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 35.45pt; text-align: center; page-break-after: avoid;"><a href="http://blog.aztec-project.org/wp-content/uploads/2010/05/keineRueckmeldung.png"><img class="aligncenter size-full wp-image-973" title="keineRueckmeldung" src="http://blog.aztec-project.org/wp-content/uploads/2010/05/keineRueckmeldung.png" alt="" width="308" height="53" /></a> Abbildung 1</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 35.45pt; text-align: justify;">
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0cm; text-align: justify;">Ein weiterer Grund für eine asynchrone Kommunikation wäre, wenn eine Anwendung nur Nachrichten verschicken möchte und es im Grunde keine Rolle spielt, ob diese Nachricht korrekt verarbeitet wurde. Vorstellbar wäre hier Loggen von Aktionen. Mir wäre es jetzt egal, ob die Nachricht korrekt gespeichert wurde oder nicht. Ich will nur nicht, dass meine Anwendung, nur weil Daten geloggt werden müssen,<span> </span>langsamer wird. Es handelt sich ja bei den Log-Daten nicht um Informationen die für die Abarbeitung notwendig sind.</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0cm; text-align: justify;">
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0cm; text-align: justify;">Ein weiterer Fall wäre z. B. das Skalieren von Datenbankabfragen. So könnten mehrere Threads gleichzeitig Daten von gleichen oder unterschiedlichen Datenbeständen abfragen um schnellere Antwortzeiten zu erhalten.</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0cm; text-align: justify;"><strong><span style="font-size: 12pt; line-height: 115%;">Beispiel</span></strong></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0cm; text-align: justify;">
Um die asynchrone Kommunikation zu realisieren gibt es unterschiedliche Möglichkeiten. Ich habe mich allerdings für eine Event-Based-Variante entschieden. Der große Vorteil von einem Event-Based Async-Pattern liegt in meinen Augen darin, dass der Nutzer von asynchrone Methoden sich nicht wirklich mit Multithread-Umgebungen auskennen muss. Für den Nutzer ist es völlig transparent wie die Threads im Hintergrund erzeugt werden und wie die Synchronisation der einzelnen Thread funktioniert. Für den Nutzer ist es nur wichtig zu wissen, dass er eine Methode aufrufen kann die asynchron abläuft und somit nicht den erwarteten Rückgabewert besitzt wie die synchrone Methode und dass ein Event ausgelöst wird, wenn die Methode komplett abgearbeitet wurde und der erwartete Rückgabewert zur Verfügung steht.</p>
<p>Nun aber genug geredet, jetzt wird programmiert. Für das Beispiel habe ich mich für eine WinForm-Anwendung entschieden, die nichts anderes tut, als die eingegebene Zahl zu quadrieren. Diese Berechnung dauert aufgrund eines Thread.Sleep() zehn Sekunden, um eine verzögerte Ausführung zu simulieren. Die Berechnung habe ich dabei in eine extra Komponente ausgelagert, die eine Schnittstelle zur asynchronen Kommunikation bereitstellt. Dabei gilt es eine gewisse Namenskonvention einzuhalten. Neben der synchronen Methode „Calc“, wird die asynchrone Methode mit dem Zusatz „Async“ bezeichnet („CalcAsync“). Da das Async-Pattern Event-Based ist, muss ein Event bereitgestellt werden, welches ausgelöst wird, wenn die asynchrone Verarbeitung beendet wurde. Laut Namenskonvention muss solch ein Event „&lt;Methodenname&gt;Completed“ heißen. Mein Event heißt somit „CalcCompleted“.</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0cm; text-align: justify;">
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0cm; text-align: justify;">Die Abbildung 2 zeigt die UI der Anwendung. Bei dem Drücken des „Run“-Buttons, soll die eingegebene Zahl asynchron quadriert werden und im Anschluss in das Feld „Ergebnis“ ausgegeben werden.</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 0cm; text-align: justify;">
<p class="MsoListParagraphCxSpLast" style="margin-left: 0cm; text-align: center; page-break-after: avoid;"><span></span></p>
<p class="MsoNormal" style="text-align: center;"><a href="http://blog.aztec-project.org/wp-content/uploads/2010/05/Form1.png"><img class="aligncenter size-full wp-image-980" title="Form1" src="http://blog.aztec-project.org/wp-content/uploads/2010/05/Form1.png" alt="" width="300" height="200" /></a>Abbildung 2</p>
<p class="MsoNormal">Der Code hinter der UI sieht folgendermaßen aus. Beim instanziieren des Forms, wird eine Instanz des Calculators erstellt und ein Delegate auf das „CalcCompleted“-Event registriert. Dieses Event wird aufgerufen sobald der Calculator mit der Berechnung fertig ist.</p>
<p class="MsoNormal">Bei dem Drücken des „Run“-Buttons, wird die Methode Calculator.CalcAsync(…) aufgerufen.</p>
<p class="MsoNormal">
<div style="font-family: Courier New; font-size: 10pt; color: black; background: white;">
<div style="font-family: Courier New; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">partial</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Form1</span> : <span style="color: #2b91af;">Form</span> {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">private</span> <span style="color: #2b91af;">ICalculator</span> m_calculator;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> Form1() {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; InitializeComponent();</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; m_calculator = <span style="color: blue;">new</span> <span style="color: #2b91af;">Calculator</span>();</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; m_calculator.CalcCompleted += Calculator_CalcCompleted;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">private</span> <span style="color: blue;">void</span> Run_Click(<span style="color: blue;">object</span> sender, <span style="color: #2b91af;">EventArgs</span> e) {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">int</span> number;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (<span style="color: #2b91af;">Int32</span>.TryParse(txbEingabe.Text, <span style="color: blue;">out</span> number)) {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; m_calculator.CalcAsync(number, number);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">void</span> Calculator_CalcCompleted(<span style="color: blue;">object</span> sender, <span style="color: #2b91af;">CalcEventArgs</span> eventArgs) {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lblCounter.Text = eventArgs.Result.ToString();</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p>
</div>
</div>
<p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;">
<p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;">
<p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;">Sobald die Berechnung fertig ist, wird das CalcCompleted-Event ausgelöst und somit die Calculator_CalcComplete-Methode aufgerufen und das Ergebnis der Berechnung in ein Label geschrieben. Der große Vorteil ist, dass man sich an dieser Stelle nicht mehr um die Synchronisierung der Threads kümmern muss, sodass man direkt auf das Label schreiben darf und es nicht zu einem threadübergreifenden Zugriff kommt.</p>
<p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;">
<p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;">Der Calculator sieht wie folgt aus:</p>
<div style="font-family: Courier New; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;</p>
<p style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">interface</span> <span style="color: #2b91af;">ICalculator</span> {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">event</span> <span style="color: #2b91af;">Calculator</span>.<span style="color: #2b91af;">CalcCompletedEventHandler</span> CalcCompleted;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">int</span> Calc(<span style="color: blue;">int</span> number);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">void</span> CalcAsync(<span style="color: blue;">int</span> number, <span style="color: blue;">object</span> userState);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Calculator</span> : <span style="color: #2b91af;">ICalculator</span> {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">delegate</span> <span style="color: blue;">void</span> <span style="color: #2b91af;">CalcCompletedEventHandler</span>(<span style="color: blue;">object</span> sender, <span style="color: #2b91af;">CalcEventArgs</span> eventArgs);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">event</span> <span style="color: #2b91af;">CalcCompletedEventHandler</span> CalcCompleted;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">private</span> <span style="color: #2b91af;">AsyncOperation</span> m_asyncOperation;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">private</span> <span style="color: blue;">bool</span> m_isRunning;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">int</span> Calc(<span style="color: blue;">int</span> number) {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: #2b91af;">Thread</span>.Sleep(10000);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">return</span> number * number;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">void</span> CalcAsync(<span style="color: blue;">int</span> number, <span style="color: blue;">object</span> userState) {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">lock</span> (<span style="color: blue;">this</span>) {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (m_isRunning) {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">InvalidOperationException</span>(<span style="color: #a31515;">&quot;Diese Operation wird bereits ausgef&#252;hrt&quot;</span>);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; m_isRunning = <span style="color: blue;">true</span>;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; m_asyncOperation = <span style="color: #2b91af;">AsyncOperationManager</span>.CreateOperation(userState);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: #2b91af;">ThreadPool</span>.QueueUserWorkItem(ExecuteCalc, number);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p>
</div>
<p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;">
<p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;">Wie man im Interface des Calculator sieht, gibt es eine synchrone und eine asynchrone Methode für die Berechnung.<span> </span>Uns interessiert allerdings nur die asynchrone Methode. Das lock und die Prüfung auf m_isRunning verhindern lediglich, dass die asynchrone Methode während ihrer Ausführung öfter aufgerufen wird. Das Wesentliche an dieser Methode ist der Aufruf von AsyncOperationManager.CreateOperation, denn dieser Aufruf stellt einen Synchronisationskontext bereit, der die Threads miteinander synchronisiert. <span> </span>Für die eigentliche Berechnung wird sich über den ThreadPool ein neuer Thread besorgt, der sich dann um die Abarbeitung der ExecuteCalc in einem eigenen Thread kümmert.</p>
<p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;">
<div style="font-family: Courier New; font-size: 10pt; color: black; background: none repeat scroll 0% 0% white;">
<div style="font-family: Courier New; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Calculator</span> : <span style="color: #2b91af;">ICalculator</span> {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">private</span> <span style="color: blue;">void</span> ExecuteCalc(<span style="color: blue;">object</span> state) {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">int</span> result = Calc((<span style="color: blue;">int</span>)state);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; m_asyncOperation.PostOperationCompleted(CalcCompletedSuccessful, result);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">private</span> <span style="color: blue;">void</span> CalcCompletedSuccessful(<span style="color: blue;">object</span> result) {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (CalcCompleted != <span style="color: blue;">null</span>) {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CalcCompleted(<span style="color: blue;">this</span>, <span style="color: blue;">new</span> <span style="color: #2b91af;">CalcEventArgs</span>(<span style="color: blue;">null</span>, <span style="color: blue;">false</span>, (<span style="color: blue;">int</span>)result, result));</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">CalcEventArgs</span> : <span style="color: #2b91af;">AsyncCompletedEventArgs</span> {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> CalcEventArgs(<span style="color: #2b91af;">Exception</span> error, <span style="color: blue;">bool</span> cancelled, <span style="color: blue;">int</span> result, <span style="color: blue;">object</span> userState)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; : <span style="color: blue;">base</span>(error, cancelled, userState) {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Result = result;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">int</span> Result { <span style="color: blue;">get</span>; <span style="color: blue;">private</span> <span style="color: blue;">set</span>; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p>
</div>
</div>
<p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"><span style="font-size: 10pt; font-family: &amp;amp;amp;"> </span></p>
<p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;">Sobald die Berechnung abgeschlossen ist, wird der Thread mit dem MainThread über den Aufruf von PostOperationCompleted synchronisiert und das CalcCompleted-Event ausgelöst und das Ergebnis in das Label geschrieben (s. o.).</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 1799px; width: 1px; height: 1px; overflow: hidden;">
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US">6</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: blue;" lang="EN-US">public</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: blue;" lang="EN-US">partial</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: blue;" lang="EN-US">class</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US">Form1</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> : </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US">Form</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> {</span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US"> 7</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: blue;" lang="EN-US">private</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US">ICalculator</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> m_calculator;</span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US"> 8</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: blue;" lang="EN-US">public</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> Form1() {</span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US"> 9</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> InitializeComponent();</span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US"> 10</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> m_calculator = </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: blue;" lang="EN-US">new</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US">Calculator</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US">();</span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US"> 11</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> m_calculator.CalcCompleted += Calculator_CalcCompleted;</span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US"> 12</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> }</span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US"> 13</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> </span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US"> 14</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: blue;" lang="EN-US">private</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: blue;" lang="EN-US">void</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> Run_Click(</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: blue;" lang="EN-US">object</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> sender, </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US">EventArgs</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> e) {</span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US"> 15</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: blue;" lang="EN-US">int</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> number;</span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US"> 16</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: blue;" lang="EN-US">if</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> (</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US">Int32</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US">.TryParse(txbEingabe.Text, </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: blue;" lang="EN-US">out</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> number)) {</span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US"> 17</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> m_calculator.CalcAsync(number, number);</span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US"> 18</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> }</span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US"> 19</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> }</span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US"> 20</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> </span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US"> 21</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: blue;" lang="EN-US">void</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> Calculator_CalcCompleted(</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: blue;" lang="EN-US">object</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> sender, </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US">CalcEventArgs</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> eventArgs) {</span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US"> 22</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;" lang="EN-US"> lblCounter.Text = eventArgs.UserState.ToString();</span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;" lang="EN-US"> </span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;">23</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;"> }</span></p>
<p style="margin: 0cm 0cm 0.0001pt; background: none repeat scroll 0% 0% white;"><span style="font-size: 10pt; font-family: &amp;amp;amp; color: #2b91af;"> 24</span><span style="font-size: 10pt; font-family: &amp;amp;amp; color: black;"> }</span></p>
</div>
<p><a href="http://dotnet-kicks.de/kick/?url=http%3a%2f%2fblog.aztec-project.org%2f2010%2f05%2f05%2fasynchrone-kommunikation-mit-dem-async-pattern%2f"><img src="http://dotnet-kicks.de/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fblog.aztec-project.org%2f2010%2f05%2f05%2fasynchrone-kommunikation-mit-dem-async-pattern%2f" alt="kick it on dotnet-kicks.de" border="0"></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.aztec-project.org%2F2010%2F05%2F05%2Fasynchrone-kommunikation-mit-dem-async-pattern%2F&amp;title=Asynchrone%20Kommunikation%20mit%20dem%20Async-Pattern" id="wpa2a_4"><img src="http://blog.aztec-project.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.aztec-project.org/2010/05/05/asynchrone-kommunikation-mit-dem-async-pattern/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>prio.conference 2009 München</title>
		<link>http://blog.aztec-project.org/2009/10/31/prio-conference-2009-munchen/</link>
		<comments>http://blog.aztec-project.org/2009/10/31/prio-conference-2009-munchen/#comments</comments>
		<pubDate>Sat, 31 Oct 2009 16:29:06 +0000</pubDate>
		<dc:creator>Thomas Christian</dc:creator>
				<category><![CDATA[prio.conference]]></category>

		<guid isPermaLink="false">http://blog.aztec-project.org/?p=707</guid>
		<description><![CDATA[In den vergangenen Tagen fand im Marriott Hotel München die prio.conference 2009 statt. Thema dieser Konferenz war in diesem Jahr „User Interface“. Dies war meine erste prio und ich muss sagen ich bin echt begeistert. Leider waren (für mich) einige interessante Sessions parallel, sodass ich mich oft nicht entscheiden konnte, welche Session ich besuchen soll. [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="size-full wp-image-708   aligncenter" title="prio_2009_468x60_statisch_01" src="http://blog.aztec-project.org/wp-content/uploads/2009/10/prio_2009_468x60_statisch_01.gif" alt="prio_2009_468x60_statisch_01" width="468" height="60" /></p>
<p>In den vergangenen Tagen fand im Marriott Hotel München die prio.conference 2009 statt. Thema dieser Konferenz war in diesem Jahr „User Interface“. Dies war meine erste prio und ich muss sagen ich bin echt begeistert. Leider waren (für mich) einige interessante Sessions parallel, sodass ich mich oft nicht entscheiden konnte, welche Session ich besuchen soll. Toll ist natürlich auch, dass sich bei solchen Veranstaltungen immer die Möglichkeiten ergeben, sich mit anderen Entwicklern zu unterhalten und zu erfahren, wie sie gewisse Dinge beurteilen, planen und umsetzen.</p>
<p>Meine besuchten Sessions:</p>
<p>-          Mein neuer PC ist ein Handy</p>
<p>-          Auflösungsunabhängige Darstellung von Benutzeroberflächen</p>
<p>-          Passive View Command Pattern – Agile User Interfaces Entwicklung mit TDD</p>
<p>-          Responsive UI’s Grundlagen</p>
<p>-          Responsive UI’s mit der Task Parallel Library</p>
<p>-          Auf dem Weg zu guten User Interfaces</p>
<p>-          Usability-Testing – ganz einfach</p>
<p>-          The IPhone as an Application Plattform for .Net Developer</p>
<p>-          Herangehensweise für das Redesign einer Software</p>
<p>-          Von der Idee zur fertigen UI – für Entwickler</p>
<p>-          Mustergültig – GUI Design-Patterns</p>
<p>-          UI – das fremde Wesen</p>
<p>Ich für meinen Teil kann sagen, dass ich viel von dieser Veranstaltung mitgenommen habe.</p>
<p>Vielen Dank</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.aztec-project.org%2F2009%2F10%2F31%2Fprio-conference-2009-munchen%2F&amp;title=prio.conference%202009%20M%C3%BCnchen" id="wpa2a_6"><img src="http://blog.aztec-project.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.aztec-project.org/2009/10/31/prio-conference-2009-munchen/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Wozu dient Reflection</title>
		<link>http://blog.aztec-project.org/2009/06/24/wozu-dient-reflection/</link>
		<comments>http://blog.aztec-project.org/2009/06/24/wozu-dient-reflection/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 10:13:06 +0000</pubDate>
		<dc:creator>Thomas Christian</dc:creator>
				<category><![CDATA[How-To]]></category>
		<category><![CDATA[Assemblies]]></category>
		<category><![CDATA[Assembly]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Reflection]]></category>

		<guid isPermaLink="false">http://blog.aztec-project.org/?p=280</guid>
		<description><![CDATA[Über Reflection kann man zur Laufzeit relativ einfach an alle Informationen eines Assembly herankommen. So ist es möglich, dass man von einem Assembly den Namen, Klassen, Methoden mit ihren Parametern, Eigenschaften und Rückgabewerte, usw. auslesen kann. Aber nicht nur das Auslesen ist möglich, sondern auch das Setzen.

Jetzt stellt sich für den einen oder anderen vielleicht die Frage, warum man zur Laufzeit auf diese Daten zugreifen kann. Jede Assembly verfügt über Module in denen sich die einzelnen Typen(Klassen) befinden. Für jedes Modul gibt es Metadaten, in denen die einzelnen Typen beschrieben werden. Die Assembly selbst verfügt noch über ein Manifest, in dem sich alle Informationen zum Assembly (z.B. Name, Version) befinden. Wenn man über Reflection auf Assemblies zugreift, dann werden diese Metadaten und das Manifest dafür herangezogen. Die Metadaten verfügen zwar noch über die Informationen, welche Modifizierer für Methoden, Properties, usw. verwendet wurden, aber der MSIL-Code (die Zwischensprache, die vom Endcompiler in die plattformspezifische Sprache übersetzt wird) nicht mehr. Die Modifizierer sind nur für den Compiler relevant und werden nach dem Kompilieren nicht mehr berücksichtigt. Somit ist es auch möglich über Reflection Properties, Methoden, usw. zu verwenden, die nicht öffentlich sind.

Für dieses Beispiel habe ich eine kleine Konsolen-Anwendung geschrieben (TestApplication), welche eine Referenz auf das Assembly TestProject.dll hat. Dieses Assembly hat zwei von mir erstellte Typen (Klassen) TestClass und SecondTestClass. In den beiden Klassen steckt keine Logik. Sie sind ausschließlich für dieses Beispiel erstellt worden, um ein paar Daten zu modifizieren und um zu zeigen wie die Informationen aus dem Assembly ausgelesen und verändert werden können und dass es möglich ist an nicht-öffentliche Methoden heranzukommen.  <a href="http://blog.aztec-project.org/2009/06/24/wozu-dient-reflection/">weiter lesen...</a>]]></description>
			<content:encoded><![CDATA[<h2><span style="color: #ffffff;">.</span></h2>
<h2>Vorbereitung</h2>
<p>Über Reflection kann man zur Laufzeit relativ einfach an alle Informationen eines Assembly herankommen. So ist es möglich, dass man von einem Assembly den Namen, Klassen, Methoden mit ihren Parametern, Eigenschaften und Rückgabewerte, usw. auslesen kann. Aber nicht nur das Auslesen ist möglich, sondern auch das Setzen.</p>
<p>Jetzt stellt sich für den einen oder anderen vielleicht die Frage, warum man zur Laufzeit auf diese Daten zugreifen kann. Jede Assembly verfügt über Module in denen sich die einzelnen Typen(Klassen) befinden. Für jedes Modul gibt es Metadaten, in denen die einzelnen Typen beschrieben werden. Die Assembly selbst verfügt noch über ein Manifest, in dem sich alle Informationen zum Assembly (z.B. Name, Version) befinden. Wenn man über Reflection auf Assemblies zugreift, dann werden diese Metadaten und das Manifest dafür herangezogen. Die Metadaten verfügen zwar noch über die Informationen, welche Modifizierer für Methoden, Properties, usw. verwendet wurden, aber der MSIL-Code (die Zwischensprache, die vom Endcompiler in die plattformspezifische Sprache übersetzt wird) nicht mehr. Die Modifizierer sind nur für den Compiler relevant und werden nach dem Kompilieren nicht mehr berücksichtigt. Somit ist es auch möglich über Reflection Properties, Methoden, usw. zu verwenden, die nicht öffentlich sind.</p>
<p>Für dieses Beispiel habe ich eine kleine Konsolen-Anwendung geschrieben (TestApplication), welche eine Referenz auf das Assembly TestProject.dll hat. Dieses Assembly hat zwei von mir erstellte Typen (Klassen) TestClass und SecondTestClass. In den beiden Klassen steckt keine Logik. Sie sind ausschließlich für dieses Beispiel erstellt worden, um ein paar Daten zu modifizieren und um zu zeigen wie die Informationen aus dem Assembly ausgelesen und verändert werden können und dass es möglich ist an nicht-öffentliche Methoden heranzukommen.</p>
<p><span style="text-decoration: underline;"><strong>TestClass.cs</strong></span></p>
<div style="background: white none repeat scroll 0% 0%; font-family: Courier New; font-size: 10pt; color: black;">
<pre style="margin: 0px;"><span style="color: blue;">using</span> System.Security.Cryptography;</pre>
<pre style="margin: 0px;"><span style="color: blue;">using</span> System.Text;</pre>
<pre style="margin: 0px;"><span style="color: blue;">namespace</span> TestProject {</pre>
<pre style="margin: 0px;"><span style="color: blue;">class</span> <span style="color: #2b91af;">TestClass</span> {</pre>
<pre style="margin: 0px;">    <span style="color: blue;">public</span> <span style="color: blue;">string</span> Name { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
<pre style="margin: 0px;">    <span style="color: blue;">public</span> <span style="color: blue;">string</span> Surname { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
<pre style="margin: 0px;">    <span style="color: blue;">private</span> <span style="color: blue;">string</span> Password { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
<pre style="margin: 0px;">    <span style="color: blue;">public</span> <span style="color: blue;">string</span> GetFullName() {</pre>
<pre style="margin: 0px;">        <span style="color: blue;">return</span> <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"{0} {1}"</span>, Name ?? <span style="color: blue;">string</span>.Empty, Surname ?? <span style="color: blue;">string</span>.Empty).Trim();</pre>
<pre style="margin: 0px;">    }</pre>
<pre style="margin: 0px;">    <span style="color: blue;">public</span> <span style="color: blue;">void</span> SetPasswort(<span style="color: blue;">string</span> password){</pre>
<pre style="margin: 0px;">        Password = password;</pre>
<pre style="margin: 0px;">    }</pre>
<pre style="margin: 0px;">    <span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: blue;">string</span> CalcPassword(<span style="color: blue;">string</span> password){</pre>
<pre style="margin: 0px;">        <span style="color: #2b91af;">MD5</span> md5 = <span style="color: #2b91af;">MD5</span>.Create();</pre>
<pre style="margin: 0px;">        <span style="color: blue;">byte</span>[] data = md5.ComputeHash(<span style="color: #2b91af;">Encoding</span>.Default.GetBytes(password));</pre>
<pre style="margin: 0px;">        <span style="color: #2b91af;">StringBuilder</span> hashPassword = <span style="color: blue;">new</span> <span style="color: #2b91af;">StringBuilder</span>();</pre>
<pre style="margin: 0px;">        <span style="color: blue;">foreach</span> (<span style="color: blue;">byte</span> b <span style="color: blue;">in</span> data){</pre>
<pre style="margin: 0px;">            hashPassword.Append(b);</pre>
<pre style="margin: 0px;">        }</pre>
<pre style="margin: 0px;">        <span style="color: blue;">return</span> hashPassword.ToString();</pre>
<pre style="margin: 0px;">    }</pre>
<pre style="margin: 0px;">    <span style="color: blue;">public</span> <span style="color: blue;">static</span> <span style="color: blue;">string</span> DoSomething(<span style="color: blue;">string</span> value) {</pre>
<pre style="margin: 0px;">        <span style="color: green;">// do something</span></pre>
<pre style="margin: 0px;">        <span style="color: blue;">return</span> value;</pre>
<pre style="margin: 0px;">    }</pre>
<pre style="margin: 0px;">}</pre>
</div>
<p><span style="text-decoration: underline;"><strong>SecondTestClass.cs</strong></span></p>
<div style="background: white none repeat scroll 0% 0%; font-family: Courier New; font-size: 10pt; color: black;">
<pre style="margin: 0px;"><span style="color: blue;">namespace</span> TestProject {</pre>
<pre style="margin: 0px;">    <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">SecondTestClass</span> {</pre>
<pre style="margin: 0px;">        <span style="color: blue;">public</span> <span style="color: blue;">int</span> Addition(<span style="color: blue;">int</span> a, <span style="color: blue;">int</span> b) {</pre>
<pre style="margin: 0px;">            <span style="color: blue;">return</span> a + b;</pre>
<pre style="margin: 0px;">        }</pre>
<pre style="margin: 0px;">        <span style="color: blue;">public</span> <span style="color: blue;">int</span> Multiply(<span style="color: blue;">int</span> a, <span style="color: blue;">int</span> b) {</pre>
<pre style="margin: 0px;">            <span style="color: blue;">return</span> a * b;</pre>
<pre style="margin: 0px;">        }</pre>
<pre style="margin: 0px;">        <span style="color: blue;">public</span> <span style="color: blue;">double</span> Divide(<span style="color: blue;">int</span> a, <span style="color: blue;">int</span> b) {</pre>
<pre style="margin: 0px;">            <span style="color: blue;">if</span> (b == 0) <span style="color: blue;">return</span> 0;</pre>
<pre style="margin: 0px;">            <span style="color: blue;">return</span> a / b;</pre>
<pre style="margin: 0px;">        }</pre>
<pre style="margin: 0px;">    }</pre>
<pre style="margin: 0px;">}
<span style="color: #ffffff;">.
.</span></pre>
</div>
<h2>Auslesen von Assembly- Type-Informationen</h2>
<p>Mit der Methode Thread.GetDomain().GetAssemblies() bekommt man alle referenzierten Assemblies der aktuellen Domäne. Damit die TestProject-Assembly auch in dieser Domäne vorhanden ist, muss vor dem Aufruf dieser Methode eine Instanz von einem Objekt dieses Assemblies erzeugt werden.</p>
<p>Um sich nun alle Assemblies der aktuellen Domäne anzeigen zu lassen, könnte man folgendes schreiben:</p>
<div style="background: white none repeat scroll 0% 0%; font-family: Courier New; font-size: 10pt; color: black;">
<pre style="margin: 0px;"><span style="color: blue;">static</span> <span style="color: blue;">void</span> Main(<span style="color: blue;">string</span>[] args) {</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">SecondTestClass</span> secondTestClass = <span style="color: blue;">new</span> <span style="color: #2b91af;">SecondTest</span><span style="color: #2b91af;"> </span><span style="color: #2b91af;">Class</span>();</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">Assembly</span>[] assemblies = <span style="color: #2b91af;">Thread</span>.GetDomain().GetAssemblies();</pre>
<pre style="margin: 0px;">    <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> assembly <span style="color: blue;">in</span> assemblies) {</pre>
<pre style="margin: 0px;">        <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"-- {0} ver.: {1}"</span>, assembly.GetName().Name
                                                          , assembly.GetName().Version));</pre>
<pre style="margin: 0px;">    }</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">Console</span>.ReadLine();</pre>
<pre style="margin: 0px;">}
<img class="size-full wp-image-281 aligncenter" src="http://blog.aztec-project.org/wp-content/uploads/2009/06/1.png" alt="1" width="549" height="120" /></pre>
</div>
<p><span style="color: #ffffff;">.</span></p>
<p>Nun könnte man noch alle zur Verfügung stehenden Typen(Klassen) aus der TestProject-Assembly anzeigen.</p>
<div style="background: white none repeat scroll 0% 0%; font-family: Courier New; font-size: 10pt; color: black;">
<div style="background: white none repeat scroll 0% 0%; font-family: Courier New; font-size: 10pt; color: black;">
<pre style="margin: 0px;"><span style="color: blue;">static</span> <span style="color: blue;">void</span> Main(<span style="color: blue;">string</span>[] args) {</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">SecondTestClass</span> secondTestClass = <span style="color: blue;">new</span> <span style="color: #2b91af;">SecondTestClass</span>();</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">Assembly</span>[] assemblies = <span style="color: #2b91af;">Thread</span>.GetDomain().GetAssemblies();</pre>
<pre style="margin: 0px;">    <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> assembly <span style="color: blue;">in</span> assemblies) {</pre>
<pre style="margin: 0px;">        <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"-- {0} ver.: {1}"</span>, assembly.GetName().Name
<pre style="margin: 0px;">                                                          , assembly.GetName().Version));</pre>
</pre>
<pre style="margin: 0px;">        <span style="color: blue;">if</span> (assembly.GetName().Name.Equals(<span style="color: #a31515;">"TestProject"</span>)) {</pre>
<pre style="margin: 0px;">            <span style="color: #2b91af;">Type</span>[] types = assembly.GetTypes();</pre>
<pre style="margin: 0px;">            <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> type <span style="color: blue;">in</span> types) {</pre>
<pre style="margin: 0px;">                <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"  ++{0}"</span>, type.Name);</pre>
<pre style="margin: 0px;">            }</pre>
<pre style="margin: 0px;">        }</pre>
<pre style="margin: 0px;">    }</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">Console</span>.ReadLine();</pre>
<pre style="margin: 0px; text-align: left;">}

<img class="size-full wp-image-284 aligncenter" title="2" src="http://blog.aztec-project.org/wp-content/uploads/2009/06/2.png" alt="2" width="533" height="130" /></pre>
</div>
</div>
<p><span style="color: #ffffff;">.</span></p>
<p>Wenn man nun allerdings Informationen eines bestimmten Types haben möchte, so werden diese Informationen aus den Metadaten des Moduls geladen, in dem sich der Type befindet. Um zum Beispiel alle öffentlichen Methoden eines Types anzuzeigen, könnte man folgendes schreiben:</p>
<div style="background: white none repeat scroll 0% 0%; font-family: Courier New; font-size: 10pt; color: black;">
<pre style="margin: 0px;"><span style="color: blue;">static</span> <span style="color: blue;">void</span> Main(<span style="color: blue;">string</span>[] args) {</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">SecondTestClass</span> secondTestClass = <span style="color: blue;">new</span> <span style="color: #2b91af;">SecondTestClass</span>();</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">Assembly</span>[] assemblies = <span style="color: #2b91af;">Thread</span>.GetDomain().GetAssemblies();</pre>
<pre style="margin: 0px;">    <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> assembly <span style="color: blue;">in</span> assemblies) {</pre>
<pre style="margin: 0px;">        <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"-- {0} ver.: {1}"</span>, assembly.GetName().Name
                                                          , assembly.GetName().Version));</pre>
<pre style="margin: 0px;">        <span style="color: blue;">if</span> (assembly.GetName().Name.Equals(<span style="color: #a31515;">"TestProject"</span>)) {</pre>
<pre style="margin: 0px;">            <span style="color: #2b91af;">Type</span>[] types = assembly.GetTypes();</pre>
<pre style="margin: 0px;">            <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> type <span style="color: blue;">in</span> types) {</pre>
<pre style="margin: 0px;">                <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"  ++ {0}"</span>, type.Name);</pre>
<pre style="margin: 0px;">                <span style="color: #2b91af;">MethodInfo</span>[] methodInfos = type.GetMethods();</pre>
<pre style="margin: 0px;">                <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> info <span style="color: blue;">in</span> methodInfos) {</pre>
<pre style="margin: 0px;">                    <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"    ++ {0}"</span>, info.Name);</pre>
<pre style="margin: 0px;">                }</pre>
<pre style="margin: 0px;">            }</pre>
<pre style="margin: 0px;">        }</pre>
<pre style="margin: 0px;">    }</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">Console</span>.ReadLine();</pre>
<pre style="margin: 0px;">}</pre>
</div>
<p align="center">
<p style="text-align: center;"><img class="size-full wp-image-285 aligncenter" title="3" src="http://blog.aztec-project.org/wp-content/uploads/2009/06/3.png" alt="3" width="629" height="383" /></p>
<p><span style="color: #ffffff;">.</span></p>
<p>Es fällt auf, dass auch die Methoden ToString, Equals, GetHashCode und GetType in beiden Klassen angezeigt werden, obwohl diese in den Klassen überhaupt nicht deklariert wurden. Das liegt daran, dass alle Typen von <span style="color: blue;">object </span>ableiten und <span style="color: blue;">object</span> diese Methoden implementiert. Was noch auffällt ist, dass nur öffentliche Methoden angezeigt werden. Möchte man sich auch die privaten Methoden anzeigen lassen, so muss man der Methode type.GetMethods Parameter übergeben. Diese Methode verlangt BindingFlags, die man mit dem Bitweise ODER-Operator (|) miteinander verknüpfen kann. Um sich nun öffentliche und private Methoden anzeigen zu lassen, muss der Aufruf der Methode type.GetMethods folgendermaßen lauten:</p>
<div style="background: white none repeat scroll 0% 0%; font-family: Courier New; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">
<pre style="margin: 0px;"><span style="color: #2b91af;">MethodInfo</span>[] methodInfos = type.GetMethods(<span style="color: #2b91af;">BindingFlags</span>.Public | <span style="color: #2b91af;">BindingFlags</span>.NonPublic | <span style="color: #2b91af;">BindingFlags</span>.Instance);</pre>
</div>
<p>Dieser Aufruf gibt an, dass man alle öffentlichen und nicht-öffentlichen Instanz-Methoden bekommen möchte. Instanz-Methoden bedeutet, dass es sich um Methoden handelt, die nur mit dem Instanzieren eines Objektes zur Verfügung stehen. D.h. es werden keine static-Methoden angezeigt. Es gibt noch weitere BindingFlags, auf die ich hier allerdings nicht weiter eingehen möchte.</p>
<p>Das ganze könnte man natürlich noch in der Form weiter treiben, dass man sich die kompletten Methodensignaturen mit Modifizierer, Schlüsselwort und Rückgabewert anzeigen lässt:</p>
<div style="background: white none repeat scroll 0% 0%; font-family: Courier New; font-size: 10pt; color: black;">
<pre style="margin: 0px;"><span style="color: blue;">static</span> <span style="color: blue;">void</span> Main(<span style="color: blue;">string</span>[] args) {</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">SecondTestClass</span> secondTestClass = <span style="color: blue;">new</span> <span style="color: #2b91af;">SecondTestClass</span>();</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">Assembly</span>[] assemblies = <span style="color: #2b91af;">Thread</span>.GetDomain().GetAssemblies();</pre>
<pre style="margin: 0px;">    <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> assembly <span style="color: blue;">in</span> assemblies) {</pre>
<pre style="margin: 0px;">        <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"-- {0} ver.: {1}"</span>, assembly.GetName().Name, assembly.GetName().Version));</pre>
<pre style="margin: 0px;">        <span style="color: blue;">if</span> (assembly.GetName().Name.Equals(<span style="color: #a31515;">"TestProject"</span>)) {</pre>
<pre style="margin: 0px;">            <span style="color: #2b91af;">Type</span>[] types = assembly.GetTypes();</pre>
<pre style="margin: 0px;">            <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> type <span style="color: blue;">in</span> types) {</pre>
<pre style="margin: 0px;">                <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"  ++ {0}"</span>, type.Name);</pre>
<pre style="margin: 0px;">                <span style="color: #2b91af;">MethodInfo</span>[] methodInfos = type.GetMethods(<span style="color: #2b91af;">BindingFlags</span>.Public | <span style="color: #2b91af;">BindingFlags</span>.NonPublic
                                                                               | <span style="color: #2b91af;">BindingFlags</span>.Instance
<pre style="margin: 0px;">                                                                               | <span style="color: #2b91af;">BindingFlags</span>.Static);</pre>
</pre>
<pre style="margin: 0px;">                <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> info <span style="color: blue;">in</span> methodInfos) {</pre>
<pre style="margin: 0px;">                    <span style="color: blue;">string</span> modifier = GetModifier(info);</pre>
<pre style="margin: 0px;">                    <span style="color: blue;">string</span> keyword = GetKeyword(info);</pre>
<pre style="margin: 0px;">                    <span style="color: blue;">string</span> parameters = GetParameters(info);</pre>
<pre style="margin: 0px;">                    <span style="color: blue;">if</span> (!<span style="color: blue;">string</span>.IsNullOrEmpty(keyword)) {</pre>
<pre style="margin: 0px;">                        keyword = <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"{0} "</span>, keyword);</pre>
<pre style="margin: 0px;">                    }</pre>
<pre style="margin: 0px;">                    <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"    ++ {0} {1}{2}{3}({4})"</span>, modifier, keyword
                                                                 , info.ReturnParameter, info.Name, parameters);</pre>
<pre style="margin: 0px;">                }</pre>
<pre style="margin: 0px;">            }</pre>
<pre style="margin: 0px;">        }</pre>
<pre style="margin: 0px;">    }</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">Console</span>.ReadLine();</pre>
<pre style="margin: 0px;">}</pre>
<pre style="margin: 0px;"><span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: blue;">string</span> GetModifier(<span style="color: #2b91af;">MethodInfo</span> info) {</pre>
<pre style="margin: 0px;">    <span style="color: blue;">if</span> (info.IsPublic) <span style="color: blue;">return</span> <span style="color: #a31515;">"public"</span>;</pre>
<pre style="margin: 0px;">    <span style="color: blue;">return</span> <span style="color: #a31515;">"private"</span>;</pre>
<pre style="margin: 0px;">}</pre>
<pre style="margin: 0px;"><span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: blue;">string</span> GetKeyword(<span style="color: #2b91af;">MethodInfo</span> info) {</pre>
<pre style="margin: 0px;">    <span style="color: blue;">if</span> (info.IsStatic) <span style="color: blue;">return</span> <span style="color: #a31515;">"static"</span>;</pre>
<pre style="margin: 0px;">    <span style="color: blue;">if</span> (info.IsVirtual) <span style="color: blue;">return</span> <span style="color: #a31515;">"virtual"</span>;</pre>
<pre style="margin: 0px;">    <span style="color: blue;">return</span> <span style="color: blue;">string</span>.Empty;</pre>
<pre style="margin: 0px;">}</pre>
<pre style="margin: 0px;"><span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: blue;">string</span> GetParameters(<span style="color: #2b91af;">MethodInfo</span> info) {</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">StringBuilder</span> parameters = <span style="color: blue;">new</span> <span style="color: #2b91af;">StringBuilder</span>();</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">ParameterInfo</span>[] parameterInfos = info.GetParameters();</pre>
<pre style="margin: 0px;">    <span style="color: blue;">if</span> (parameterInfos != <span style="color: blue;">null</span>) {</pre>
<pre style="margin: 0px;">        <span style="color: blue;">foreach</span> (<span style="color: #2b91af;">ParameterInfo</span> parameterInfo <span style="color: blue;">in</span> parameterInfos) {</pre>
<pre style="margin: 0px;">            <span style="color: blue;">if</span> (!<span style="color: blue;">string</span>.IsNullOrEmpty(parameters.ToString())) {</pre>
<pre style="margin: 0px;">                parameters.Append(<span style="color: #a31515;">", "</span>);</pre>
<pre style="margin: 0px;">            }</pre>
<pre style="margin: 0px;">            parameters.AppendFormat(<span style="color: #a31515;">"{0} {1}"</span>, parameterInfo.ParameterType.Name, parameterInfo.Name);</pre>
<pre style="margin: 0px;">        }</pre>
<pre style="margin: 0px;">    }</pre>
<pre style="margin: 0px;">    <span style="color: blue;">return</span> parameters.ToString();</pre>
<pre style="margin: 0px;">}</pre>
</div>
<p style="text-align: center;"><img class="size-full wp-image-287 aligncenter" title="4" src="http://blog.aztec-project.org/wp-content/uploads/2009/06/4.png" alt="4" width="605" height="443" /></p>
<p><span style="color: #ffffff;">.</span></p>
<p>Nicht immer ist bereits während der Entwicklung bekannt, aus welchem Assembly man Informationen benötigt. Sodass die Methode Thread.GetDomain().GetAssemblies() nicht verwendet werden kann. Eine weitere Möglichkeit an ein Assembly zu kommen ist es direkt zu laden. Dafür bietet die Klasse Assembly die statische Methode Assembly.LoadFrom zum Laden von Assemblies. Statt dem Laden des Assembly über die aktuelle Domäne, wird das nächste Beispiel so modifiziert, dass die TestProject-Assembly direkt aus einem Verzeichnis heraus geladen wird.</p>
<div style="background: white none repeat scroll 0% 0%; font-family: Courier New; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">
<pre style="margin: 0px;"><span style="color: blue;">static</span> <span style="color: blue;">void</span> Main(<span style="color: blue;">string</span>[] args) {</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">Assembly</span> assembly = <span style="color: #2b91af;">Assembly</span>.LoadFrom(<span style="color: #a31515;">@"c:\TestProject.dll"</span>);</pre>
<pre style="margin: 0px;">    <span style="color: blue;">if</span> (assembly != <span style="color: blue;">null</span>) {</pre>
<pre style="margin: 0px;">        <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"-- {0} ver.: {1}"</span>, assembly.GetName().Name, assembly.GetName().Version));</pre>
<pre style="margin: 0px;">        <span style="color: #2b91af;">Type</span>[] types = assembly.GetTypes();</pre>
<pre style="margin: 0px;">        <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> type <span style="color: blue;">in</span> types) {</pre>
<pre style="margin: 0px;">            <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"  ++ {0}"</span>, type.Name);</pre>
<pre style="margin: 0px;">            <span style="color: #2b91af;">MethodInfo</span>[] methodInfos =</pre>
<pre style="margin: 0px;">            type.GetMethods(<span style="color: #2b91af;">BindingFlags</span>.Public | <span style="color: #2b91af;">BindingFlags</span>.NonPublic | <span style="color: #2b91af;">BindingFlags</span>.Instance |</pre>
<pre style="margin: 0px;">            <span style="color: #2b91af;">BindingFlags</span>.Static);</pre>
<pre style="margin: 0px;">            <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> info <span style="color: blue;">in</span> methodInfos) {</pre>
<pre style="margin: 0px;">                <span style="color: blue;">string</span> modifier = GetModifier(info);</pre>
<pre style="margin: 0px;">                <span style="color: blue;">string</span> keyword = GetKeyword(info);</pre>
<pre style="margin: 0px;">                <span style="color: blue;">string</span> parameters = GetParameters(info);</pre>
<pre style="margin: 0px;">                <span style="color: blue;">if</span> (!<span style="color: blue;">string</span>.IsNullOrEmpty(keyword)) {</pre>
<pre style="margin: 0px;">                    keyword = <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"{0} "</span>, keyword);</pre>
<pre style="margin: 0px;">                }</pre>
<pre style="margin: 0px;">                <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"    ++ {0} {1}{2}{3}({4})"</span>, modifier, keyword, info.ReturnParameter,</pre>
<pre style="margin: 0px;">                info.Name, parameters);</pre>
<pre style="margin: 0px;">            }</pre>
<pre style="margin: 0px;">        }</pre>
<pre style="margin: 0px;">    }</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">Console</span>.ReadLine();</pre>
<pre style="margin: 0px;">}</pre>
</div>
<p align="center">
<div id="attachment_288" class="wp-caption aligncenter" style="width: 687px"><img class="size-full wp-image-288" title="5" src="http://blog.aztec-project.org/wp-content/uploads/2009/06/5.png" alt="5" width="677" height="419" /><p class="wp-caption-text">Man sieht, dass die gleiche Ausgabe wie bereits im vorherigen Beispiel generiert wird.</p></div>
<p style="text-align: center;">
<h2><span style="color: #ffffff;">.</span></h2>
<h2>Interaktionen</h2>
<p>Nachdem die Vorgehensweise nun klar sein sollte, möchte ich nun den eigentlich interessanten Teil demonstrieren. Wie kann man nun auf Methoden usw. zugreifen und wie können Werte aus einem Type gelesen und veränder werden? Wenn man die Methode SecondTestClass.Addition(int a, int b) aufrufen möchte, dann braucht man die Methodeninformationen von dem Type SecondTestClass aus dem TestProject-Assembly. D.h. man muss wie in den obigen Beispielen auch über alle Typen iterieren, um an den gesuchten Type SecondTestClass zu kommen. Hat man den gesuchten Type gefunden, so kann man sich von diesem alle Methoden in einem Array zurückgeben lassen. Dieses Array kann dann wieder ganz normal durchlaufen und nach der gewünschten Methode durchsucht werden. Hat man die Methode gefunden so muss zuerst eine Instanz von dem Objekt erzeugt werden und dafür gibt es den Activator, der die statische Methode CreateInstance beinhaltet. Als Parameter übergibt man ihr den Type von dem eine Instanz erzeugt werden soll. Jetzt kann man über die MethodInfo die Methode aufrufen. Dazu muss der Methode die Instanz des Objektes übergeben werden, von welchem die Methode aufgerufen werden soll und zusätzlich noch ein Array von Objekten, welche die zu übergebenen Parameter beinhaltet. Hat die Methode keine Parameter, so muss null übergeben werden. Dabei muss der Rückgabewert in den erwarteten Wert gecastet werden. Das ganze könnte dann folgendermaßen aussehen:</p>
<div style="background: white none repeat scroll 0% 0%; font-family: Courier New; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">
<pre style="margin: 0px;"><span style="color: blue;">static</span> <span style="color: blue;">void</span> Main(<span style="color: blue;">string</span>[] args) {</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">Assembly</span> assembly = <span style="color: #2b91af;">Assembly</span>.LoadFrom(<span style="color: #a31515;">@"c:\TestProject.dll"</span>);</pre>
<pre style="margin: 0px;">    <span style="color: blue;">if</span> (assembly != <span style="color: blue;">null</span>) {</pre>
<pre style="margin: 0px;">        <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"-- {0} ver.: {1}"</span>, assembly.GetName().Name, assembly.GetName().Version));</pre>
<pre style="margin: 0px;">        <span style="color: #2b91af;">Type</span>[] types = assembly.GetTypes();</pre>
<pre style="margin: 0px;">        <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> type <span style="color: blue;">in</span> types) {</pre>
<pre style="margin: 0px;">            <span style="color: blue;">if</span> (type.Name.Equals(<span style="color: #a31515;">"SecondTestClass"</span>)) {</pre>
<pre style="margin: 0px;">                <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"  ++ {0}"</span>, type.Name);</pre>
<pre style="margin: 0px;">                <span style="color: #2b91af;">MethodInfo</span>[] methodInfos = type.GetMethods();</pre>
<pre style="margin: 0px;">                <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> info <span style="color: blue;">in</span> methodInfos) {</pre>
<pre style="margin: 0px;">                    <span style="color: blue;">if</span> (info.Name.Equals(<span style="color: #a31515;">"Addition"</span>)) {</pre>
<pre style="margin: 0px;">                        <span style="color: blue;">object</span> obj = <span style="color: #2b91af;">Activator</span>.CreateInstance(type);</pre>
<pre style="margin: 0px;">                        <span style="color: blue;">int</span> value = (<span style="color: blue;">int</span>)info.Invoke(obj, <span style="color: blue;">new</span> <span style="color: blue;">object</span>[] { 2, 5 });</pre>
<pre style="margin: 0px;">                        <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"    ++ {0}(2 + 5) = {1}"</span>, info.Name, value);</pre>
<pre style="margin: 0px;">                    }</pre>
<pre style="margin: 0px;">                }</pre>
<pre style="margin: 0px;">            }</pre>
<pre style="margin: 0px;">        }</pre>
<pre style="margin: 0px;">    }</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">Console</span>.ReadLine();</pre>
<pre style="margin: 0px;">}</pre>
</div>
<p align="center">
<div id="attachment_289" class="wp-caption aligncenter" style="width: 543px"><img class="size-full wp-image-289" title="6" src="http://blog.aztec-project.org/wp-content/uploads/2009/06/6.png" alt="6" width="533" height="143" /><p class="wp-caption-text">Aufruf der Methode Addition</p></div>
<p style="text-align: center;">
<p><span style="color: #ffffff;">.</span></p>
<p>Bei statischen Methoden kann das Erzeugen der Instanz weggelassen werden und für den Parameter des Instanz-Objektes kann null übergeben werden.</p>
<div style="background: white none repeat scroll 0% 0%; font-family: Courier New; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">
<pre style="margin: 0px;"><span style="color: blue;">if</span> (type.Name.Equals(<span style="color: #a31515;">"TestClass"</span>)) {</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"  ++ {0}"</span>, type.Name);</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">MethodInfo</span>[] methodInfos = type.GetMethods(<span style="color: #2b91af;">BindingFlags</span>.NonPublic | <span style="color: #2b91af;">BindingFlags</span>.Static);</pre>
<pre style="margin: 0px;">    <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> info <span style="color: blue;">in</span> methodInfos) {</pre>
<pre style="margin: 0px;">        <span style="color: blue;">if</span> (info.Name.Equals(<span style="color: #a31515;">"CalcPassword"</span>)) {</pre>
<pre style="margin: 0px;">            <span style="color: blue;">string</span> value = (<span style="color: blue;">string</span>)info.Invoke(<span style="color: blue;">null</span>, <span style="color: blue;">new</span> <span style="color: blue;">object</span>[] { <span style="color: #a31515;">"myPassword"</span> });</pre>
<pre style="margin: 0px;">            <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"    ++ {0}(\"myPassword\") = {1}"</span>, info.Name, value);</pre>
<pre style="margin: 0px;">        }</pre>
<pre style="margin: 0px;">    }</pre>
<pre style="margin: 0px;">}</pre>
</div>
<p align="center">
<div id="attachment_290" class="wp-caption aligncenter" style="width: 687px"><img class="size-full wp-image-290" title="7" src="http://blog.aztec-project.org/wp-content/uploads/2009/06/7.png" alt="7" width="677" height="155" /><p class="wp-caption-text">Das übergebene Passwort wurde über eine statische Methode gehashed.</p></div>
<p style="text-align: center;">
<p><span style="color: #ffffff;">.</span></p>
<p>Um den Wert einer Property auszulesen, muss anstelle von MethodInfo die PropertyInfo verwendet werden. Aus dieser kann dann über die Methode PropertyInfo.GetValue der aktuelle Wert zurückgegeben werden. Da in diesem Beispiel nach dem Instanzieren des Objektes noch keine Werte zugewiesen wurden, sind die Properties leer.</p>
<div style="background: white none repeat scroll 0% 0%; font-family: Courier New; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">
<pre style="margin: 0px;"><span style="color: blue;">static</span> <span style="color: blue;">void</span> Main(<span style="color: blue;">string</span>[] args) {</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">Assembly</span> assembly = <span style="color: #2b91af;">Assembly</span>.LoadFrom(<span style="color: #a31515;">@"C:\ TestProject.dll"</span>);</pre>
<pre style="margin: 0px;">    <span style="color: blue;">if</span> (assembly != <span style="color: blue;">null</span>) {</pre>
<pre style="margin: 0px;">        <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"-- {0} ver.: {1}"</span>, assembly.GetName().Name, assembly.GetName().Version));</pre>
<pre style="margin: 0px;">        <span style="color: #2b91af;">Type</span>[] types = assembly.GetTypes();</pre>
<pre style="margin: 0px;">        <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> type <span style="color: blue;">in</span> types) {</pre>
<pre style="margin: 0px;">            <span style="color: blue;">if</span> (type.Name.Equals(<span style="color: #a31515;">"TestClass"</span>)) {</pre>
<pre style="margin: 0px;">                <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"  ++ {0}"</span>, type.Name);
<pre style="margin: 0px;"><span style="color: blue;">                object</span> obj = <span style="color: #2b91af;">Activator</span>.CreateInstance(type);</pre>
</pre>
<pre style="margin: 0px;">                <span style="color: #2b91af;">PropertyInfo</span>[] propertyInfos = type.GetProperties(<span style="color: #2b91af;">BindingFlags</span>.Public | <span style="color: #2b91af;">BindingFlags</span>.NonPublic
                                                                                      | <span style="color: #2b91af;">BindingFlags</span>.Instance);</pre>
<pre style="margin: 0px;">                <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> info <span style="color: blue;">in</span> propertyInfos) {</pre>
<pre style="margin: 0px;">                    <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"    ++ {0} = {1}"</span>, info.Name, info.GetValue(obj, <span style="color: blue;">null</span>));</pre>
<pre style="margin: 0px;">                }</pre>
<pre style="margin: 0px;">            }</pre>
<pre style="margin: 0px;">        }</pre>
<pre style="margin: 0px;">    }</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">Console</span>.ReadLine();</pre>
<pre style="margin: 0px;">}
<img class="aligncenter size-full wp-image-373" title="8" src="http://blog.aztec-project.org/wp-content/uploads/2009/06/8.png" alt="8" width="517" height="203" /></pre>
</div>
<p><span style="color: #ffffff;">.</span></p>
<p>Wenn man nun die Properties mit Werten belegen möchte, so muss man analog zur Methode PropertyInfo.GetValue, die Methode PropertyInfo. SetValue verwenden.</p>
<div style="background: white none repeat scroll 0% 0%; font-family: Courier New; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">
<pre style="margin: 0px;"><span style="color: blue;">if</span> (type.Name.Equals(<span style="color: #a31515;">"TestClass"</span>)) {</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"  ++ {0}"</span>, type.Name);</pre>
<pre style="margin: 0px;">    <span style="color: #2b91af;">PropertyInfo</span>[] propertyInfos = type.GetProperties(<span style="color: #2b91af;">BindingFlags</span>.Public | <span style="color: #2b91af;">BindingFlags</span>.NonPublic
                                                                          | <span style="color: #2b91af;">BindingFlags</span>.Instance);</pre>
<pre style="margin: 0px;">    propertyInfos[0].SetValue(obj, <span style="color: #a31515;">"Peter"</span>, <span style="color: blue;">null</span>);</pre>
<pre style="margin: 0px;">    propertyInfos[1].SetValue(obj, <span style="color: #a31515;">"Müller"</span>, <span style="color: blue;">null</span>);</pre>
<pre style="margin: 0px;">    propertyInfos[2].SetValue(obj, <span style="color: #a31515;">"myPassword"</span>, <span style="color: blue;">null</span>);</pre>
<pre style="margin: 0px;">    <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> info <span style="color: blue;">in</span> propertyInfos) {</pre>
<pre style="margin: 0px;">        <span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"    ++ {0} = {1}"</span>, info.Name, info.GetValue(obj, <span style="color: blue;">null</span>));</pre>
<pre style="margin: 0px;">    }</pre>
<pre style="margin: 0px;">}
<img class="aligncenter size-full wp-image-374" title="9" src="http://blog.aztec-project.org/wp-content/uploads/2009/06/9.png" alt="9" width="477" height="167" /></pre>
</div>
<p><strong> </strong></p>
<h2><span style="color: #ffffff;">.</span></h2>
<p><span style="color: #ffffff;">.<br />
</span></p>
<h2>Wozu braucht man jetzt aber nun die Reflection?</h2>
<p>Nun ja, die meisten Programme werden Reflection wohl nie benötigen oder verwenden. Es wird vorallem bei dem Entwickeln von Debuggern, Interpretern, TestTools, Logger oder auch für O/R-Mapper verwendet. Es wird also überall dort gebraucht, wo während der Laufzeit nicht klar ist, welche Assemblies verwendet werden und welche Informationen man aus diesen lesen oder manipulieren möchte.</p>
<h2><span style="color: #ffffff;">.</span></h2>
<h2>kurze Zusammenfassung:</h2>
<p>Wie man gesehen hat, ist der Aufbau einer Assembly mit ihren Typen hierarchisch. Um zb. an einen Parameter einer Methode eines Types zu kommen, braucht man zuerst das Assembly welches den Typ enthält. Von diesem lässt man sich ein Array von Typen geben. Von dem gesuchten Typ lässt man sich dann ein Array von Methoden geben. Von der gesuchten Methode holt man sich nun ein Array von allen Parametern. Dieses Array kann dann nach dem gewünschten Parameter durchsucht werden.</p>
<p>Es gibt natürlich für all diese Methoden auch Methoden, mit denen man sich den Type, die Methodeninformation, die Parameterinformation, usw. direkt mit der entsprechenden Bezeichnung holen kann. Ich wollte hier nur auf die Hierarchie aufmerksam machen.</p>
<p>Wie man in diesen Beispielen erkennen konnte, ist es möglich, ohne Probleme auf alle Informationen von einem Assembly zuzgreifen, sich die Types zu laden, dessen öffentliche und auch nicht-öffentliche Werte zu lesen und zu manipulieren und auch Methoden auszuführen. Man kann sich auch lokale Werte anzeigen lassen, in dem man sich den MethodBody des Objekte geben lässt, von denen man die lokalen Werte ermitteln möchte.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aztec-project.org/2009/06/24/wozu-dient-reflection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clean-Code-Developer</title>
		<link>http://blog.aztec-project.org/2009/06/06/clean-code-developer/</link>
		<comments>http://blog.aztec-project.org/2009/06/06/clean-code-developer/#comments</comments>
		<pubDate>Sat, 06 Jun 2009 12:05:28 +0000</pubDate>
		<dc:creator>Thomas Christian</dc:creator>
				<category><![CDATA[Clean Code Developing]]></category>
		<category><![CDATA[Tipps]]></category>
		<category><![CDATA[Architektur]]></category>

		<guid isPermaLink="false">http://blog.aztec-project.org/?p=132</guid>
		<description><![CDATA[Heute habe ich einen recht interessanten Artikel gelesen. In diesem ging es darum besseren Code zu schreiben, zu warten und im allgemeinen besser mit ihm umzugehen. Die Rede ist dabei von Clean-Code-Developer. Dabei geht es weder darum neue Technologien zu verwenden, noch darum neue Sprachen zu erlernen. Eigentlich ist es eher ein kleiner Leitfaden um [...]]]></description>
			<content:encoded><![CDATA[<p>Heute habe ich einen recht interessanten Artikel gelesen. In diesem ging es darum besseren Code zu schreiben, zu warten und im allgemeinen besser mit ihm umzugehen. Die Rede ist dabei von <a href="http://www.clean-code-developer.de" target="_blank">Clean-Code-Developer</a>.</p>
<p>Dabei geht es weder darum neue Technologien zu verwenden, noch darum neue Sprachen zu erlernen. Eigentlich ist es eher ein kleiner Leitfaden um  sich stetig zu verbessern, und das wollen wir doch im Allgemeinen eh, sonst würde dieser Blog-Eintrag wohl auch nicht gelesen.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.aztec-project.org%2F2009%2F06%2F06%2Fclean-code-developer%2F&amp;title=Clean-Code-Developer" id="wpa2a_8"><img src="http://blog.aztec-project.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.aztec-project.org/2009/06/06/clean-code-developer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Dynamisches Laden von Assemblies</title>
		<link>http://blog.aztec-project.org/2009/06/05/dynamisches-laden-von-assemblies/</link>
		<comments>http://blog.aztec-project.org/2009/06/05/dynamisches-laden-von-assemblies/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 19:57:46 +0000</pubDate>
		<dc:creator>Thomas Christian</dc:creator>
				<category><![CDATA[How-To]]></category>
		<category><![CDATA[Assembly]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Reflection]]></category>

		<guid isPermaLink="false">http://blog.aztec-project.org/?p=50</guid>
		<description><![CDATA[In diesem Blog-Post möchte ich kurz erläutern, wie ich mit dem Problem des dynamischen Ladens von Assemblies umgegangen bin. Vor einiger Zeit stand ich vor dem Problem, dass ich zur Laufzeit Assemblies austauschen wollte. Grund dafür war, dass ich eine Host-Applikation hatte, die Plug-Ins verwendet. Jetzt wollte ich bestehende Plug-Ins während der Laufzeit austauschen oder [...]]]></description>
			<content:encoded><![CDATA[<p>In diesem Blog-Post möchte ich kurz erläutern, wie ich mit dem Problem des dynamischen Ladens von Assemblies umgegangen bin.</p>
<p>Vor einiger Zeit stand ich vor dem Problem, dass ich zur Laufzeit Assemblies austauschen wollte. Grund dafür war, dass ich eine Host-Applikation hatte, die Plug-Ins verwendet. Jetzt wollte ich bestehende Plug-Ins während der Laufzeit austauschen oder neue Plug-Ins hinzufügen ohne die Host-Applikation zu beenden. Dazu hatte ich ein Verzeichnis in dem sich, außer den Plug-Ins, alle Assemblies befanden. Die Plug-Ins selbst befanden sich in einem eigenen Unterverzeichnis. Selbst wenn die Plug-Ins von der Host-Applikation nicht mehr verwendet wurden, war es nicht möglich, diese Assemblies zu löschen.</p>
<p>Im Normalfall ist es so, dass sobald eine Assembly von einer Applikation verwendet wird, eine Referenz auf diese existiert. Diese Referenz wird leider erst gelöscht, wenn die ganze Applikation beendet wird.</p>
<p>Bei dem dynamischen Laden von Assemblies wird die zu ladende Assembly geöffnet, ausgelesen und dann geschlossen. Aus den ausgelesenen Bytes wird dann mittels Reflection eine Assembly im Arbeitsspeicher erzeugt. Auf die lokale Assembly hängt somit keine Referenz und es ist möglich diese zu löschen.</p>
<p>Meine Umsetzung sieht folgendermaßen aus:</p>
<div style="font-family: Courier New; font-size: 10pt; color: black; background: white;">
<pre style="margin: 0px;"><span style="color: #2b91af;">    2</span> <span style="color: blue;">public</span> IList&lt;Plugin&gt; GetPlugins(<span style="color: blue;">string</span> assemblyName) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    3</span>     Assembly assembly;</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    4</span>     IList&lt;Plugin&gt; pluginList = <span style="color: blue;">new</span> IList&lt;Plugin&gt;();</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    5</span>     <span style="color: blue;">try</span> {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    6</span>         <span style="color: blue;">byte</span>[] byteAssembly = File.ReadAllBytes(assemblyName);</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    7</span>         assembly = Assembly.Load(byteAssembly);</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    8</span>     } <span style="color: blue;">catch</span> (Exception ex) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    9</span>         log.Error(ex);</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   10</span>     }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   11</span>     <span style="color: blue;">try</span> {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   12</span>         <span style="color: blue;">if</span> (assembly != <span style="color: blue;">null</span>) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   13</span>             Type[] assemblyTypes = assembly.GetTypes();</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   14</span>             <span style="color: blue;">foreach</span> (Type assemblyTyp <span style="color: blue;">in</span> assemblyTypes) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   15</span>                 <span style="color: blue;">if</span> (<span style="color: blue;">typeof</span>(Plugin).IsAssignableFrom(assemblyTyp)) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   16</span>                     plugin = (Plugin)assembly.CreateInstance(assemblyTyp</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   17</span>                                                                 .FullName);</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   18</span>                     <span style="color: blue;">if</span> (plugin != <span style="color: blue;">null</span>) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   19</span>                         pluginList.Add(plugin);</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   20</span>                     }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   21</span>                 }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   22</span>             }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   23</span>         }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   24</span>     } <span style="color: blue;">catch</span> (ReflectionTypeLoadException ex) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   25</span>         log.Error(ex);</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   26</span>     }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   27</span>     <span style="color: blue;">return</span> pluginList;</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   28</span> }</pre>
</div>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.aztec-project.org%2F2009%2F06%2F05%2Fdynamisches-laden-von-assemblies%2F&amp;title=Dynamisches%20Laden%20von%20Assemblies" id="wpa2a_10"><img src="http://blog.aztec-project.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.aztec-project.org/2009/06/05/dynamisches-laden-von-assemblies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Umsetzung des Plug-In-Patterns</title>
		<link>http://blog.aztec-project.org/2009/06/05/umsetzung-des-plug-in-patterns/</link>
		<comments>http://blog.aztec-project.org/2009/06/05/umsetzung-des-plug-in-patterns/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 19:45:57 +0000</pubDate>
		<dc:creator>Thomas Christian</dc:creator>
				<category><![CDATA[How-To]]></category>
		<category><![CDATA[Architektur]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Plug-In]]></category>

		<guid isPermaLink="false">http://blog.aztec-project.org/?p=5</guid>
		<description><![CDATA[In meinem ersten Blog-Post möchte ich euch in vereinfachter Form meine Umsetzung des Plug-In-Patterns vorstellen. Voraussetzungen für dieses Pattern sind: eine Host-Applikation die das Plug-In laden möchte ein Plug-In welches es zu laden gilt und die Schnittstellen Plugin und IHost Zu allererst brauchen wir eine gemeinsame Schnittstelle, die sowohl vom Plug-In als auch vom Host [...]]]></description>
			<content:encoded><![CDATA[<p>In meinem ersten Blog-Post möchte ich euch in vereinfachter Form meine Umsetzung des Plug-In-Patterns vorstellen.<br />
Voraussetzungen für dieses Pattern sind:</p>
<ul>
<li> eine Host-Applikation die das Plug-In laden möchte</li>
<li> ein Plug-In welches es zu laden gilt</li>
<li> und die Schnittstellen Plugin und IHost</li>
</ul>
<p>Zu allererst brauchen wir eine gemeinsame Schnittstelle, die sowohl vom Plug-In als auch vom Host (die Applikation welche das Plug-In verwenden soll) benutzt werden soll. Über diese Schnittstelle kommuniziert der Host mit dem Plug-In.<br />
Es würde sich das Interface IPlugIn anbieten. In meinem Fall verwende ich allerdings kein Interface sondern eine abstrakte Klasse, da ich bereits Logik direkt in die Schnittstelle implementieren möchte. In meinem Fall heißt die abstrakte Klasse einfach nur Plugin. Im weiteren Verlauf werde ich zu meiner abstrakten Klasse Schnittstelle sagen.</p>
<div style="font-family: Courier New; font-size: 10pt; color: black; background: white;">
<pre style="margin: 0px;"><span style="color: #2b91af;">    1</span> <span style="color: blue;">public</span> <span style="color: blue;">abstract</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Plugin</span> {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    2</span>     <span style="color: blue;">private</span> IHost m_host;</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    3</span>     <span style="color: blue;">public</span> Plugin(<span style="color: blue;">string</span> name) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    4</span>         Name = name;</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    5</span>     }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    6</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    7</span>     <span style="color: blue;">public</span> <span style="color: blue;">string</span> Name { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    8</span>     <span style="color: blue;">public</span> <span style="color: blue;">string</span> Author { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    9</span>     <span style="color: blue;">public</span> <span style="color: blue;">string</span> Version { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   10</span>     <span style="color: blue;">public</span> <span style="color: blue;">bool</span> IsRegistered { <span style="color: blue;">get</span>; <span style="color: blue;">private</span> <span style="color: blue;">set</span>; }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   11</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   12</span>     <span style="color: gray;">///</span><span style="color: green;"> </span><span style="color: gray;">&lt;summary&gt;</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   13</span>     <span style="color: gray;">///</span><span style="color: green;"> Setzt oder gibt die Host-Application.</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   14</span>     <span style="color: gray;">///</span><span style="color: green;"> </span><span style="color: gray;">&lt;/summary&gt;</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   15</span>     <span style="color: gray;">///</span><span style="color: green;"> </span><span style="color: gray;">&lt;value&gt;</span><span style="color: green;">Host-Application.</span><span style="color: gray;">&lt;/value&gt;</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   16</span>     <span style="color: blue;">public</span> IHost Host {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   17</span>         <span style="color: blue;">get</span> { <span style="color: blue;">return</span> m_host; }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   18</span>         <span style="color: blue;">set</span> {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   19</span>             <span style="color: blue;">if</span> (<span style="color: blue;">value</span> != <span style="color: blue;">null</span>) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   20</span>                 <span style="color: blue;">if</span> (m_host == <span style="color: blue;">null</span>) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   21</span>                     m_host = <span style="color: blue;">value</span>;</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   22</span>                     <span style="color: blue;">if</span> (m_host.Register(<span style="color: blue;">this</span>)) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   23</span>                         IsRegistered = <span style="color: blue;">true</span>;</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   24</span>                     }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   25</span>                 }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   26</span>             } <span style="color: blue;">else</span> {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   27</span>                 <span style="color: blue;">if</span> (m_host.Unregister(<span style="color: blue;">this</span>)) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   28</span>                     m_host = <span style="color: blue;">value</span>;</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   29</span>                     IsRegistered = <span style="color: blue;">false</span>;</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   30</span>                 }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   31</span>             }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   32</span>         }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   33</span>     }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   34</span> }</pre>
</div>
<p>Ich glaube, der Aufbau der Schnittstelle Plugin sollte bis auf die Property “Host” klar sein. Wie man sieht, benötigt man bei diesem Pattern zusätzlich zur Schnittstelle Plugin noch das IHost-Interface.<br />
Dieses Interface ist direkter Bestandteil der Schnittstelle Plugin. Nun kann man sich natürlich die Frage stellen, warum das Plug-In den Host kennen muss und somit von diesem abhängig ist.</p>
<p>Zum einen ist es in der Regel so, dass ein Plug-In für nur einen Host entwickelt wird und zum anderen wollte ich dem Host gewisse Richtlinien zum Registrieren und Lösen des Plug-Ins vorgeben.</p>
<p>Das Interface IHost sieht folgendermaßen aus:</p>
<div style="font-family: Courier New; font-size: 10pt; color: black; background: white;">
<pre style="margin: 0px;"><span style="color: #2b91af;">    1</span> <span style="color: blue;">public</span> <span style="color: blue;">interface</span> <span style="color: #2b91af;">IHost</span> {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    2</span>     <span style="color: blue;">bool</span> Register(Plugin plugin);</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    3</span>     <span style="color: blue;">bool</span> Unregister(Plugin plugin);</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    4</span> }</pre>
</div>
<p>Dieses Interface muss von der Host-Applikation implementiert werden, damit sich das Plug-In am Host registrieren kann. Im letzten Satz habe ich es schon angedeutet. Nicht der Host registriert das Plug-In bei sich, sondern das Plug-In registriert sich am Host. Durch das setzen der Property Plugin.Host wird die Methode Register oder Unregister vom Plug-In aufgerufen, welche der Host implementiert.</p>
<p>Eine vereinfachte Darstellung der Implementierung des IHost -Interfaces sieht folgendermaßen aus:</p>
<div style="font-family: Courier New; font-size: 10pt; color: black; background: white;">
<pre style="margin: 0px;"><span style="color: #2b91af;">    1</span> <span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">HostApplication</span> : IHost {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    2</span>     <span style="color: blue;">private</span> List&lt;Plugin&gt; m_pluginList;</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    3</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    4</span>     <span style="color: green;">//Konstruktor</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    5</span>     <span style="color: blue;">public</span> HostApplication() {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    6</span>         m_pluginList = <span style="color: blue;">new</span> List&lt;Plugin&gt;();</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    7</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    8</span>         <span style="color: green;">//Lädt alle verfügbaren Plug-Ins zb. aus einem Verzeichnis</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">    9</span>         List&lt;Plugin&gt; plugins = GetPlugins();</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   10</span>         <span style="color: blue;">foreach</span> (Plugin plugin <span style="color: blue;">in</span> plugins) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   11</span>             <span style="color: green;">//ruft implizit die IHost.Register-Methode auf</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   12</span>             plugin.Host = <span style="color: blue;">this</span>;</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   13</span>         }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   14</span>     }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   15</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   16</span>     <span style="color: blue;">public</span> <span style="color: blue;">void</span> ShowPlugins() {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   17</span>         <span style="color: blue;">foreach</span> (Plugin plugin <span style="color: blue;">in</span> m_pluginList) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   18</span>             <span style="color: green;">//Ausgabe der Namen aller am Host registrierten Plug-Ins</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   19</span>             Console.WriteLine(plugin.Name);</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   20</span>         }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   21</span>     }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   22</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   23</span>     <span style="color: blue;">public</span> <span style="color: blue;">void</span> UnloadPlugins() {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   24</span>         <span style="color: blue;">foreach</span> (Plugin plugin <span style="color: blue;">in</span> m_pluginList) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   25</span>             <span style="color: green;">//ruft implizit die IHost.Unregister-Methode auf</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   26</span>             plugin.Host = <span style="color: blue;">null</span>;</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   27</span>         }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   28</span>     }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   29</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   30</span> <span style="color: blue;">    #region</span> IHost-Implementierung</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   31</span>     <span style="color: blue;">public</span> <span style="color: blue;">bool</span> Register(Plugin plugin) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   32</span>         <span style="color: blue;">if</span> (!m_pluginList.Contains(plugin)) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   33</span>             m_pluginList.Add(plugin);</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   34</span>             <span style="color: blue;">return</span> <span style="color: blue;">true</span>;</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   35</span>         }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   36</span>         <span style="color: blue;">return</span> <span style="color: blue;">false</span>;</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   37</span>     }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   38</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   39</span>     <span style="color: blue;">public</span> <span style="color: blue;">bool</span> Unregister(Plugin plugin) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   40</span>         <span style="color: blue;">if</span> (m_pluginList.Contains(plugin)) {</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   41</span>             m_pluginList.Remove(plugin);</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   42</span>             <span style="color: blue;">return</span> <span style="color: blue;">true</span>;</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   43</span>         }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   44</span>         <span style="color: blue;">return</span> <span style="color: blue;">false</span>;</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   45</span>     }</pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   46</span> <span style="color: blue;">    #endregion</span></pre>
<pre style="margin: 0px;"><span style="color: #2b91af;">   47</span> }</pre>
</div>
<p>Das Registrieren und Lösen der Plug-Ins könnte man nun noch in einen Plug-In-Manager auslagern, worauf ich in diesem Blog allerdings verzichten möchte.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.aztec-project.org%2F2009%2F06%2F05%2Fumsetzung-des-plug-in-patterns%2F&amp;title=Umsetzung%20des%20Plug-In-Patterns" id="wpa2a_12"><img src="http://blog.aztec-project.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.aztec-project.org/2009/06/05/umsetzung-des-plug-in-patterns/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

