6 Stimmen

.NET-Typdefinitionen in zusammengeführten Assemblys (ILMerge)

Ich fusioniere mehrere .NET-Assemblys mit ILMerge, einschließlich einiger Assemblys von Drittanbietern. Seitdem habe ich mehrere Fehler erlebt, die alle darauf zurückzuführen sind, dass Typdefinitionen an die Assembly gebunden sind, in der sie definiert sind.

Ein einfaches Beispiel ist die Definition des log4net-Konfigurationsabschnitts in meiner App.config. Es verwendet type="log4net.Config.Log4NetConfigurationSectionHandler, log4net", was nicht funktionieren wird, da die log4net-Assembly nicht mehr existiert, nachdem sie in meine fusionierte Assembly zusammengeführt wurde. Aber das ist kein großes Problem, ich ändere einfach den Assemblynamen auf meine fusionierte Assembly und es funktioniert einwandfrei.

Ein etwas komplizierteres Beispiel sind binär serialisierte Typen. Mein System verwendet die binäre Serialisierung, um bestimmte Objekte zwischen Prozessen zu senden. Alle serialisierbaren Objekte sind in einer gemeinsamen Assembly definiert, auf die alle anderen Projekte verweisen. Ich habe die Standard-Binärserialisierung verwendet, aber sie begann zu versagen, als die Objekte deserialisiert wurden, mit dem Fehler, dass die zusammengeführte Assembly, die das Objekt serialisiert hat, nicht gefunden werden konnte. Auch hier kein großes Problem, ich habe einen benutzerdefinierten SerializationBinder implementiert, der nach dem Typ in einer beliebigen geladenen Assembly sucht, nicht nur in der angegebenen.

Das vorherige Beispiel wurde komplizierter, als der serialisierte Typ auf andere serialisierbare Typen verweist. Ich stoße weiterhin auf mehr und mehr Probleme, die immer schwieriger zu bewältigen sind.

Der Punkt, den ich hier machen möchte, ist, dass das .NET-Typsystem und ILMerge scheinbar nicht gut miteinander funktionieren. Hat jemand Erfahrung damit, wie sie dieses Problem gelöst haben? Ist es möglich, dem .NET-Runtime mitzuteilen, dass es nicht wichtig ist, in welcher Assembly der Typ sein sollte, einfach überall danach suchen?

HINWEIS: Bitte antworten Sie nicht mit der Frage, warum ich Assemblys zusammenführe, das ist nicht der Sinn dieser Frage.

0 Stimmen

WAG: Hast du den DataContractSerializer schon ausprobiert? Du wirst es nicht können mit dem NetDataContractSerializer, da er an Typen gebunden ist, aber der einfache DataContractSerializer sollte für dich funktionieren...

4voto

Task Punkte 3590

Ja, es gibt eine Lösung für dieses Problem: Erstellen Sie Module anstelle von Assemblys!

Compiler für .net haben eine Option (/target:module für C# und VB), die ein Modul anstelle einer Assembly erstellt. Mehrere Module können dann an den Compiler übergeben und für den Aufbau der endgültigen Assembly verwendet werden.

Natürlich setzt das voraus, dass Sie den Quellcode dieser Drittanbieter-Assemblys haben. Wenn Sie das nicht bekommen können, vielleicht kann eine .netmodule-Version der Drittanbieter-Assembly vom Drittanbieter beschafft werden?

Wenn das nicht funktioniert, haben Sie noch eine letzte Option. Offensichtlich disassemblieren Sie bereits eine Drittanbieter-Assembly in IL. Entfernen Sie die Assembly-Informationen aus dieser IL-Datei und verwenden Sie "ilasm /dll", um ein .netmodule zu erstellen, das Sie jetzt wie jedes andere .netmodule verwenden sollten!

Durch die Verwendung von Modulen anstelle von Assemblys sollten Sie keine Probleme mehr mit Assembly-basierten haben.

Richtig, wir haben Ihr Problem mit ILMerge gelöst, indem wir ILMerge nicht mehr verwenden, aber ist das nicht wirklich die beste Lösung?

Ich hoffe, es funktioniert für Sie, hier sind einige nützliche Links:
.netmodul anstelle von Assembly
ILASM mit .netmodulen

(Und da dachte ich, dass meine Erfahrung mit .netmodulen nie für irgendjemanden nützlich sein würde!)

0voto

peval27 Punkte 1159

Einige Jahre nach der Frage stieß ich auf das gleiche Problem und fand eine Lösung. Du kannst [assembly: log4net.Config.XmlConfigurator(ConfigFile = "logging.config", Watch = true)] in die Datei AssemblyInfo.cs hinzufügen und dies wird funktionieren, wenn du die log4net-Assembly fusionierst.

-2voto

rama-jka toti Punkte 1374

Willkommen bei den Gefahren von Zeichenfolgen und (physical-location) Zeichenfolgen im Code.

Alle Werkzeuge dieser Art haben ähnliche Probleme und sie sollten besser intelligent sein, da viele Entwickler und Designer von Laufzeitfunktionen wie Bindung und Serialisierung es nicht wirklich vorgesehen haben, aber sie haben definitiv ILMerge als ein 'intelligentes' Werkzeug gepusht. Es ist so intelligent, dass es nicht einmal Typen beschneiden kann.

Beachten Sie, dass auch hier die Versionierung eine Rolle spielt, sowie Konfiguration, .* und Sterne-in-den-Augen, und Versionenunabhängigkeit von Redmond helfen auch nicht weiter.

Sie werden mit Sicherheit auf Probleme mit Drittanbieter-Bits stoßen. Und glauben Sie mir, ich weiß, dass Sie das Zusammenführen brauchen, da einige armselige kleine Anzahl von Typen für große Apps ewig benötigen, damit MS JIT eingreift (und nein, ich möchte kein NGEN oder optimiertes 3.5SP1-Laden, das noch langsamer ist als zuvor aufgrund von System.Core oder wehe, WPF-Blähungen ).

Meiner Meinung nach ist die beste Option zumindest im großen Maßstab, ein ordentliches kommerzielles Tool zu verwenden, das dies scannt und handhabt (d.h. aufgrund der vorhandenen Schmerzen und der Verschleierungserfahrung da draußen). In der langen Perspektive könnten Sie vorhandenem IL-Code Instrumente hinzufügen, wenn Sie die Quellen nicht haben.

[ Dann gab es die Erfindung einer INotifyPropertyChanged-Zeichenfolge, die das Problem der globalen Erwärmung so gelöst hat - entworfen von den Casio-Calc-Erfindern ]

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X