Kuriose Phänomene mit dem .NET Framework Client Profile
Die von Visual Studio 2010 automatisch vorgenommene Reduzierung einiger Projekte auf das .NET Framework Client Profile kann zu auf den ersten Blick nicht erklärbaren Fehlermeldungen des C#-Compilers führen.
- Dr. Holger Schwichtenberg
Ich glaubte zunächst, dass Microsofts C# Compiler (völlig) durchdreht, als durch das Ändern einer Codezeile die DLL zwar noch kompilierte, aber der Compiler dann die Namensräume dieses Kompilate in einem anderen Projekt nicht mehr finden wollte. Schuld an dem Phänomen war Visual Studios Umgang mit dem .NET Framework Client Profile beziehungsweise eine nicht hilfreiche Fehlermeldung in Visual Studio.
Den echten Vorfall kann ich hier kaum wiedergeben, weil es sich um ein sehr komplexes Entwicklungsprojekt fĂĽr einen Enterprise Service Bus (ESB) handelt, den ich seit einigen Wochen im Kundenauftrag entwickele. Ich werde das Problem daher einmal herunterbrechen auf ein einfacheres Beispiel.
- Projekt A: Konsolenanwendungs-EXE, Namensraum NA
- Projekt B: DLL, Namensraum NB
- Projekt A referenziert Projekt B.
- Projekt B referenziert diverse Klassen aus dem .NET Framework 4.0
- Alles kompiliert und läuft korrekt.
Nun ändere ich in Projekt B eine Codezeile, ich tausche eine .NET-Framework-Klasse K1 (etwa BasicHttpBinding) gegen eine andere K2 (zum Beispiel WebHttpBinding) mit der gleichen Basisklasse. Projekt B kompiliert immer noch korrekt. Aber Projekt A kompiliert nicht mehr. Die Fehlermeldung von Visual Studio sagt, dass Namensraum NB in A nicht gefunden werden kann. Dabei findet Projekt A immer noch die B-DLL, aber der Compiler kann den Inhalt nicht mehr "sehen".
Des Rätsels Lösung liegt tatsächlich in der Sichtbarkeit in Verbindung mit dem .NET Framework Client Profile . Es ist eine abgespeckte Variante des .NET Framework, die auf alle Bibliotheken verzichtet, die (typischerweise) nur in Serveranwendungen verwendet werden. Visual Studio 2010 legt alle Konsolenanwendungen (so auch "Projekt A") mit dem .NET Framework Client Profile an.
Projekt B war nicht auf dem Client Profile konfiguriert, weil es Assemblies aus dem .NET Framework referenzierte, die nur zum kompletten .NET Framework gehörten. Alles funktionierte, solange B an seinen in A verwendeten Schnittstellen die Klasse K1 (beispielsweise BasicHttpBinding) zurückgab, die es im .NET Client Profil gibt. Sobald aber die nicht im Client Profile vorhandene Klasse K2 (etwa WebHttpBinding) verwendet wurde, sah Visual Studio ein Problem für das Projekt A.
Anstelle einer ordentlichen Fehlermeldung hat Visual Studio dann aber das Kompilat von B aus dem Kompilierungsvorgang von A einfach ausgeblendet – nach dem Motto: Ich schließe die Augen, dann sehe ich das Problem nicht. Das Resultat war die kuriose Fehlermeldung, dass der ganze Namensraum NB aus Projekt B in A nicht mehr gefunden wurde.
Wenn man das verstanden hat, ist die Lösung einfach: Projekt A muss für das komplette .NET Framework anstelle des .NET Framework Client Profile kompiliert werden.
An dem Problem habe nicht nur ich einige staunende Minuten verbracht, sondern auch meine Kollegen Jörg Neumann (der unter anderem mit mir an dem ESB-Projekt arbeitet) und Daniel Fisher (der mit mir .NET-Schulungen durchführt). Daniels erster Kommentar, als er mir in einem Büro über die Schulter auf mein ESB-Projekt schaute: "Du weißt, dass du die kritische Masse von 20 Projekten in einer Projektmappe in Visual Studio überschritten hast?" Daniel Fisher kam aber schließlich auf die tatsächliche Ursache. Danke, Daniel! ()