Montag, 9. November 2009

NUnit im STA - Modus

Neulich hatte ich die Anforderung, dass ein Programm Daten der Zwischenablage nutzen und modifizieren sollte. Ich habe (natürlich) angefangen einen Test zu schreiben. Leider war dies mit dem Unit-Test-Tool meiner Wahl (NUnit) nicht möglich. Der Fehler:
System.Threading.ThreadStateException: Der aktuelle Thread muss in den STA-Modus (Singlethreadapartment) gesetzt werden, bevor OLE-Aufrufe durchgeführt werden können.
Der Fehler tritt im Übrigen auch auf, wenn man versucht UserControls zu testen und sollte für WPF und WinForms gleich sein.
Die Lösung des Problems: NUnit-Tests im Single-Threaded Apartment (STA) statt in der Vorgabe (Multithreaded Apartment (MTA)) laufen lassen. Das Vorgehen: Man erstellt eine einfache app.config mit folgendem Inhalt:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <sectionGroup name="NUnit">
            <section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>
        </sectionGroup>
    </configSections>
    <NUnit>
        <TestRunner>
            <!-- Valid values are STA,MTA. Others ignored. -->
            <add key="ApartmentState" value="STA" />
            <!-- See ThreadPriority enum for other valid values -->
            <add key="ThreadPriority" value="Normal" />
        </TestRunner>
    </NUnit>
</configuration>
Damit läuft NUnit im STA, und die es kann auf die Zwischenablage zugegriffen werden.
Die Lösung habe ich von hier.

Dienstag, 3. November 2009

ReportPropertyChanged vs. OnPropertyChanged in Entities

Gerade etwas länger mit folgender Fehlermeldung gerungen: System.ArgumentException: Die Eigenschaft 'Foo' weist keine gültige Entitätszuordnung für das Entitätsobjekt auf. Weitere Informationen finden Sie in der Dokumentation zu Entity Framework.
Der Fehler trat immer auf,  wenn ich Foo einen wert zuweisen wollte.

Ursache des Fehlers war, das ich meinem eigenen Post über Zusammengesetzte Properties nicht gefolgt war, sondern statt dessen auf diversen Settern noch ReportPropertyChanged("Foo") programmiert hatte.
ReportPropertyChanged ist abernicht das gleiche wie OnPropertyChanged. ReportPropertyChanged scheint noch mehr zu tun und funktioniert daher nur auf Properties aus Enities mit Entitätszuordnung.
Nachdem ich den Fehler gefunden hatte machte die Fehlermeldung auf einmal auch viel mehr sinn.
Die Lösung des Problems war also einfach nicht ReportPropertyChanged zu benutzen, sondern OnPropertyChanged.
(Und bei dieser gelegenheit noch einmal mein Vorgehen in diesem Fall zu überdenken, und mich etwas mehr an meine eigenen Posts halten.)