2009-11-05 5 views
6

Ich füge mehrere .NET-Assemblys mit ILMerge zusammen, einschließlich einiger Drittanbieter-Assemblys. Seitdem habe ich mehrere Fehler, die alle auf die Tatsache, dass Typdefinitionen an die Assembly gebunden sind, in denen sie definiert sind gebunden sind..NET-Typdefinitionen in zusammengeführten Assemblys (ILMerge)

Ein einfaches Beispiel ist die Log4net Config Abschnitt Definition in meiner App.config. Es verwendet type = "log4net.Config.Log4NetConfigurationSectionHandler, log4net", das nicht funktioniert, da die log4net-Assembly nicht existiert, nachdem sie in meine zusammengeführte Assembly eingefügt wurde. Keine große Sache, ich ändere den Assemblynamen in meine zusammengeführte Assembly und es funktioniert gut.

Ein etwas komplizierteres Beispiel sind binäre serialisierte Typen. Mein System verwendet 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 standardmäßige binäre Serialisierung verwendet, aber sie hat beim Deserialisieren der Objekte mit dem Fehler fehlgeschlagen, dass die zusammengefügte Assembly, die das Objekt serialisiert hat, nicht gefunden werden konnte. Wiederum keine große Sache, ich habe einen benutzerdefinierten SerializationBinder implementiert, der nach dem Typ in jeder geladenen Assembly sucht, nicht nur nach dem angegebenen.

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

Der Punkt, den ich hier versuche, ist, dass das .NET-Typsystem und ILMerge nicht gut zusammen zu spielen scheinen. Hat jemand Erfahrung damit, wie sie dieses Problem gelöst haben? Ist es möglich, der .NET-Laufzeit zu sagen, dass es mir egal ist, in welcher Assembly der Typ heißt, in der sie sich befinden sollte, einfach irgendwo danach suchen?

HINWEIS: Bitte antworten Sie nicht, fragen, warum ich Assemblys zusammenführen, das ist nicht der Punkt dieser Frage.

+0

WAG: Haben Sie den DataContractSerializer schon versucht? Sie können nicht mit dem NetDataContractSerializer, da es an Typen gebunden ist, aber das einfache alte DCS sollte für Sie arbeiten ... – Will

Antwort

-2

Willkommen bei Gefahren von Strings und (physikalisch-Standort) Strings im Code ..

Alle Werkzeuge dieser Art haben ähnliche Probleme und sie besser sein, smart, wie viele Entwickler und Designer von Runtime-Funktionen wie Bindung und Die Serialisierung hat es nicht wirklich ins Auge gefasst, aber sie haben ILMerge als ein "intelligentes" Werkzeug gedrängt. Es ist so schlau, dass es nicht einmal Arten beschneiden kann.

Beachten Sie, dass die Versionierung auch hier ins Spiel kommt, und Konfiguration,. * Und Sterne in ihren Augen, und Versionsunabhängigkeit von Redmond hilft auch nicht.

Sie werden sicher weiterhin Probleme mit Thirdy Party Bits bekommen. Und glauben Sie mir, ich weiß, dass Sie die Verschmelzung brauchen, da einige erbärmliche kleine Typen von Typen für MS JIT für große Apps ewig brauchen können (und nein, ich möchte nicht NGEN oder optimiertes Laden von 3.5SP1, das sogar langsamer als vorher ist aufgrund von System.Core oder Himmelsverbot WPF aufblähen).

Beste Option, imho, zumindest in großem Maßstab, ist ein anständiges kommerzielles Werkzeug, das scannt und behandelt dies (dh von der bestehenden Schmerz und Verschleierung Erfahrung da draußen). Auf lange Sicht könnten Sie den vorhandenen IL-Code instrumentieren, wenn Sie die Quellen nicht haben.

[Dann gab es eine INotifyPropertyChanged Zeichenfolge Erfindung, die so die globale Erwärmung Problem gelöst - gestaltet von Casio-Calc Erfinder]

4

Ja, eine Lösung gibt für dieses Problem ist: Build-Module anstelle von Baugruppen!

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

Natürlich geht das alles davon aus, dass Sie die Quelle für diese Baugruppen von Drittanbietern haben. Wenn Sie das nicht bekommen können, kann vielleicht eine .netmodule Version der 3rd Party Assembly von der 3rd Party bezogen werden?

Wenn das nicht funktioniert, haben Sie noch eine letzte Option. Offensichtlich zerlegen Sie bereits eine Baugruppe eines Drittherstellers in IL. Entfernen Sie die Baugruppeninformationen aus dieser IL-Datei und verwenden Sie "ilasm/dll", um ein .NET-Modul zu erstellen, das Sie nun wie jedes andere .netmodul verwenden können!

Wenn Sie Module anstelle von Baugruppen verwenden, sollten Sie keine Probleme mehr mit Baugruppen haben.

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

Hoffe, dass es für Sie arbeitet, hier einige handliche Bindung:
.netmodule instead of assembly
ILASM with .netmodules

(Und hier dachte ich, dass meine Erfahrung mit .netmodules nie jemandem nützlich sein würde!)

0

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