4

Ist es möglich, eine Assembly zu schreiben, die dynamisch eine neue Klasse erzeugt/ausgibt und sich selbst patcht, um die neue Klasse aufzunehmen?Ist es möglich, eine Assembly zu schreiben, die dynamisch eine neue Klasse generiert und sich selbst mit der neuen Klasse patcht?

Wie?

+0

Was genau möchten Sie erreichen? Es könnte einen anderen Weg für das geben, was du machen willst, denke ich. – Kirtan

+0

Nur versuchen, die Frage zu klären. In C# ist es möglich, mit System.CodeDom und System.CodeDom.Compiler Code zur Laufzeit zu generieren und zu kompilieren, die resultierende neue Assembly zu laden und über Reflektion aufzurufen. Ihre Frage hört sich so an, als ob Sie das nicht möchten. Sie möchten eine vorhandene Baugruppe patchen. Verstehe ich das richtig? – Accipitridae

+0

Ich habe eine Assembly auf SQLServer bereitgestellt, die über Datenklassen verfügt, die mit benutzerdefinierten Attributen versehen sind. Für jede markierte Klasse erstelle ich eine statische Methode, die im SQL Server als skalare CLR-Funktion registriert wird und in Prüfbedingungen verwendet wird. Jede Funktion versucht, eine Klasse zu instanziieren und gibt für den Erfolg true zurück. Dies vereinheitlicht die Datentypen in meiner Anwendung mit der Datenbank. Um zu vermeiden, dass diese Liste von Funktionen beibehalten wird, erzeuge ich dynamisch die Klasse und die Funktionen. Diese Klasse wurde früher in derselben Assembly von Hand codiert, aber jetzt ist sie dynamisch. Ich möchte eine einzige DLL. – Triynko

Antwort

2

fragte ich diese Frage eine andere Art und Weise hier: Using AssemblyBuilder, how can I make all or any of the referenced assemblies embedded instead of linked in the saved assembly?

die vorhandene DLL mit dem dynamisch generierten Code Patchen in der gleichen Sache würde die ursprüngliche DLL in der dynamisch generierten Code als Einbettungs - eine einzige Anordnung mit dem Inhalt von beiden.

Es scheint, dass eine oder andere Weise, Abhängigkeiten zu beseitigen und den Inhalt mehrerer Baugruppen in einem Satz, das ILMerge Dienstprogramm die eleganteste Lösung ist.

Das einzige Problem ist, dass die Typen in der fusionierten dll erzeugt sind unvereinbar mit den gleichen Arten in beiden ursprünglichen DLLs. Wenn die ursprüngliche DLL beispielsweise eine neue Assembly ausgibt, sie mit sich selbst zusammenführt und die neue Assembly lädt ... kann sie nicht ihre eigenen Typen verwenden, um auf Dinge in der neuen Assembly zu verweisen, die demselben Typ in einem der beiden entsprechen Original-Baugruppen.

Mit anderen Worten: Klasse A in [dll_generator] Referenzen [dll_1]. Klasse A erzeugt [dll_2], was auf [dll_1] und natürlich auch auf [dll_1] basiert. Klasse A ruft ILMerge auf, um [dll_2] mit seiner Abhängigkeit [dll_1] zu kombinieren, um [dll_merged] zu erzeugen. Keiner der Typen in [dll_merged] ist mit einem seiner ursprünglichen Typen in [dll_1] und [dll_2] kompatibel. Wenn also Klasse A [dll_merged] lädt und versucht, irgendetwas damit zu tun, wobei Literaltypnamen von seiner ursprünglichen Referenz auf [ dll_1], schlägt fehl, weil die Typen inkompatibel sind. Der einzige Weg, wie Klasse A mit Typen in [dll_merged] arbeiten kann, besteht darin, sie nach Namen zu laden und vollständig mit "Type" -Objekten und Reflektionen zu arbeiten - oder Quellcode dynamisch gegen den neuen [dll_merged] zu kompilieren.

1

Der beste Weg, dies zu tun ist, Dependency Injection/Umkehrung der Steuerung zu verwenden oder auch einen einfachen Service locater.

Ihre neue Montage würde eine neue konkrete Umsetzung schaffen und dass anstelle der alten Implementierung registrieren.

Ich bin sicher, dass etwas exotischere wäre in der Tat eine schreckliche Hack.

+0

Können Sie das mehr erklären? Grundsätzlich muss ich eine Assembly bereitstellen und die Klasse, die darin handcodiert wurde, wird jetzt dynamisch generiert. Ich möchte diese Klasse in der ursprünglichen Assembly haben, aber ich wollte, dass sie dynamisch von der Assembly erzeugt wird, anstatt von mir manuell codiert zu werden. Ist das möglich? – Triynko

+0

Etwas wie Autofac oder Windsor kann verwendet werden, um konkrete Implementierungen von Klassen zu registrieren, die dann aus dem Container injiziert oder aus ihm zurückgeliefert werden. Es ist eine einfache Möglichkeit, um Ihre Implementierungen zu organisieren (und das ist eine schrecklich einfache Erklärung). Wenn Sie Ihre Software so umgestalten, dass die ursprüngliche Implementierung aus einem Container oder Service Locator stammt, können Sie diese mit einer benutzerdefinierten Implementierung leicht überschreiben (solange das Original nicht versiegelt ist) –

+0

Ich denke nicht das ist, was ich suche. Die Datenklassen existieren bereits, und ich erweiterte die DLL nur um automatisch generierte Funktionen, die jede Datenklasse instanziieren und als CLR-Funktionen in SQL Server registriert werden können. Dazu muss der dynamisch generierte Code in der ursprünglichen DLL enthalten sein. Bis jetzt ist die Lösung, die ich verwende, ILMerge nur als Post-Emit-Schritt zu verwenden, und das funktioniert gut. – Triynko