wake-up-neo.com

Kann ich eine .NET 4.0-Bibliothek in einer .NET 2.0-Anwendung verwenden?

Bei der Verwendung meiner .NET 4.0-Bibliotheken in .NET 2.0-Anwendungen treten einige Probleme auf. Ich glaube, ich hatte den Eindruck, dass meine anderen .NET-Apps als Windows-DLL darauf zugreifen können. Ist das nicht der Fall? Gibt es Empfehlungen zur Unterstützung von Anwendungen in beiden Umgebungen?

EDIT: Mir ist klar, dass ich .NET 4.0 Framework auf dem Zielsystem installieren muss. Gibt es andere Gründe, warum dies nicht funktioniert/nicht funktionieren sollte?

EDIT: Sollte wahrscheinlich genauer sein. Wir haben eine aktuelle, große/komplexe Anwendung, die in .NET 2.0 geschrieben ist (genau gesagt in ASP.NET). Wir haben eine Reihe neuer Integrationstools und Workflow-Elemente, die wir in .NET 4.0 schreiben. Wir wollten dem .NET 2.0-Projekt (derzeit in VS2008) eine der mit 4.0 erstellten Bibliotheken hinzufügen und einige ihrer Methoden anwenden. Wenn wir dies tun, stoßen wir auf Probleme, häufig auf kryptische Speicherfehler.

Es scheint, dass sowohl Earwicker als auch Brian Rasmussen am Ende richtig sind. Da ich nicht besonders daran interessiert bin, Dinge über COM offenzulegen (nicht sicher, ob dies technisch COM ist oder nicht, aber unabhängig davon), denke ich, dass ich mich an die Idee halten werde, dass die beiden nicht „kompatibel“ sind und nach anderen Mitteln Ausschau halten, die ich denke Wir haben uns auf unsere spezifischen Bedürfnisse eingestellt. Längerfristig werden wir versuchen, den .NET 2.0-Code auf 4.0 zu verschieben.

30

Ja, das ist durchaus möglich. Sie machen nur die in 4.0 geschriebenen Komponenten als COM-Objekte verfügbar. Die 2.0-Hosting-Anwendung verwendet sie nur als COM-Objekte und hat keine Ahnung, ob sie nativ, 2.0, 4.0 oder was auch immer sind. COM ist die gemeinsame Schnittstelle, die beide Laufzeitversionen identisch implementieren müssen. 

Die neue In-Process-SxS-Unterstützung in 4.0 bedeutet, dass beim Laden des 4.0-basierten COM-Objekts die erforderliche Laufzeit abgerufen wird, anstatt unter 2.0 ausgeführt zu werden. Daher sind beide Laufzeiten im Prozess vorhanden, der ihre eigenen Objekte verwaltet. Obwohl Sie CLR-Objekte nicht direkt zwischen ihnen übergeben können, können Sie COM-Schnittstellen übergeben, und die CLR bindet Ihre Objekte transparent in COM-Schnittstellen für Sie ein.

Ich weiß nicht, ob Sie eine einzige Interop-Assembly für beide Versionen erstellen können. Aber Sie könnten natürlich eine Interop-Assembly in C # in 2.0 schreiben, sie in eine .tlb exportieren und dann in eine Assembly in 4.0 importieren. Damit haben Sie zwei passende Interop-Baugruppen, die identische COM-Schnittstellen beschreiben. (Oder erstellen Sie einfach die gleiche C # -Quelle im Assembly-Projekt jeder Version).

Bonus Update: Wird die resultierende Anwendung COM-basiert sein (mit allen Problemen, die damit einhergehen)?

Es hängt davon ab, wie Sie es betrachten. Komponentenautoren werden als COM-Komponenten erstellt. Die Host-Anwendung muss sie also als COM-Komponenten suchen und laden. Das bedeutet, mit dem GAC, der Registry oder den SxS-Manifesten herumzuspielen, was viel weniger sauber ist, als nur den Komponentenautoren zu sagen, dass sie ihre Assembly in einem bestimmten Verzeichnis ablegen müssen, um sie mit Reflektion zu laden.

Das hat Auswirkungen auf die Laufzeit: Wenn der Host einen Verweis auf eine Komponente hat, wird nicht ein Objekt, sondern ein drei - Objekt beteiligt. Der Host verfügt über eine Referenz auf eine RCW, die einen Zeiger auf eine von einer CCW implementierte COM-Schnittstelle enthält, die wiederum eine Referenz auf die tatsächliche Komponente enthält. Das CCW in der Mitte ist ein COM-Objekt mit Referenzzähler, und das RCW des Host verfügt über ein Finalizer, das Release im CCW aufruft. Wenn es zerstört wird, hebt es die GCRoot auf, die die tatsächliche Komponente am Leben erhält.

Dies bedeutet, dass das System bei einer ausreichend komplizierten Anordnung von Rückrufzeigern usw. zu Kreiszählproblemen führen kann, bei denen eine getrennte "Insel" von Objekten jeweils Referenzen zueinander enthält und daher nicht freigegeben wird.

23

Bitte beachten Sie, dass Version 4.0 mehr ist als nur zusätzliche Baugruppen. Die Laufzeit selbst wurde in dieser Version ebenfalls geändert (neuer gleichzeitiger GC-Modus, viele Änderungen am Thread-Pool, mscorwks.dll heißt jetzt clr.dll usw.). 

10
Brian Rasmussen

Ich habe gerade einen Post veröffentlicht, im Wesentlichen was Daniel vorschlug.

So verwenden Sie ein .NET 4-basiertes DLL aus einer .NET 2-basierten Anwendung

Quellcode und Beschreibung unter: http://code.msdn.Microsoft.com/User-a-NET-4-Based-DLL-bb141db3

10
arik

Je nach Verwendung kann es möglich sein. In .Net 4.0 haben Sie die Möglichkeit der In-Prozess-Side-by-Side-Ausführung (InProc SxS). Dadurch können Sie zwei verschiedene CLR-Versionen im selben Prozessbereich hosten. Dies ist hier erklärt

Ob Sie dies in Ihrer Situation nutzen können, weiß ich nicht. Ich habe keine direkte Erfahrung, um Ihnen zu helfen. 

Einige Szenarien , in denen dies verwendet werden kann.

3
softveda

Anscheinend würde die in-Prozess-Side-by-Side-Funktion, die zu CLR 4 hinzugefügt wurde, in diesem Fall nicht helfen, da er eine .NET4.0-Bibliothek in einer .NET2.0-Anwendung verwenden möchte. Soweit ich es verstehe, wäre In-Process-SxS hilfreich, wenn das Gegenteil der Fall wäre (ein .NET 2.0 in einer .NEt4.0-Anwendung verbrauchend), da die CLR der 4.0 neben 2.0 in der Version 2.0 funktionieren wird der gleiche Prozess ..

1
Derar

Ihre für .NET 4 kompilierte Assembly enthält Verweise auf andere .NET 4-Framework-Bibliotheken, die in .NET 2.0 nicht vorhanden sind. 

Wenn Sie möchten, dass Ihre Anwendungen mit .NET 2.0 kompatibel sind, können Sie Visual Studio 2005 oder target Ihre Projekte für .NET 2.0 verwenden, wenn Sie Visual Studio 2008 oder 2010 verwenden. Natürlich, wenn Sie Ihre Projekte als Ziel verwenden. Mit NET 2.0 können Sie die Funktionen von .NET 3.5/4 nicht nutzen.

0
Daniel Melo

Ich hatte ein ähnliches Problem mit meiner Anwendung, bei der ich nicht auf eine API verweisen konnte, die .net 4.0-Komponenten verwendete.
Um dieses Problem zu beheben, habe ich ein neues Klassenbibliothekprojekt erstellt, das auf mein .net 4.0-Projekt verwies, und dann diese neue Assembly von meinem .net 2.0-Projekt aufgerufen. Ich habe die von .net zurückkommenden Daten zugeordnet 4.0-Projekt, das von meinem .net 2.0-Projekt verwendet werden soll.
Das hat mein Problem gelöst. 

0
savvyBrar