2014-03-30 12 views
5

Ich habe mit ILDasm um gespielt und habe bemerkt, dass:ILDasm Mscorlib und System.Runtime Dekompilierungsprozeß Unterschiede auf das Verzeichnis, in Abhängigkeit

  • Decompiling C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Runtime.dll (36KB) einfach eine Manifest-Datei zurückgibt. Dekompilierung C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\System.Runtime.dll (114KB) gibt das Manifest und alle Typen in der Assembly zurück.

  • Dekompilierung C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\mscorlib.dll (38KB) gibt einfach eine Manifestdatei zurück und dekompiliert C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll (5171KB) gibt ein Manifest und alle Typen in der Baugruppe zurück.

Ich kann keine Informationen darüber finden, warum die Baugruppen so gebaut sind.

Was sind die Unterschiede in den zwei Assembly-Verzeichnissen und warum haben zwei Kopien auf dem Dateisystem? Warum werden Typen in beiden Baugruppen dupliziert? Sowohl System.Runtime als auch mscorlib enthalten die meisten der gleichen Typen.

Antwort

13

Die in C: \ Programme (x86) \ Reference Assemblies gefundenen Assemblys sind Referenz-Assemblies. Sie sind ziemlich speziell in .NET 4.0 und höher, sie enthalten keinen Code, nur die Typdeklarationen. Ein Compiler verwendet nur die Metadaten in einer solchen Assembly, um Ihren Code zu kompilieren. Zur Laufzeit erhalten Sie eine sehr andere Baugruppe, die aus dem GAC abgerufen wird.

Sie beachten, dass Sie viele Kopien von System.Runtime.dll in diesem Verzeichnis finden, hat das .NETPortable Verzeichnis insbesondere viele Profile mit jeweils eigenen Kopie dieser Bezugsanordnung. Mit verschiedenen Arten von Typen, die für das jeweilige Profil geeignet sind.

Die Assemblys, die Sie in C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 gefunden haben, sind eine Kopie der im GAC enthaltenen Assemblys. Welche Version des Frameworks Sie auch tatsächlich installiert haben. Sie sollten nie verwenden diese Baugruppen für alles. Während viele Assemblys dort noch eine [AssemblyVersion ("4.0.0.0")] haben, ist ihr Inhalt dramatisch anders, insbesondere zwischen 4.0 und 4.5. Sie können dies in der Dokumentation sehen, die ExtensionAttribute class ist ein gutes Beispiel. In .NET 4.0 lebt es in System.Core.dll, in 4.5 und höher lebt es jetzt in mscorlib.dll. Es wäre besser, wenn diese Kopien nicht mehr da wären, leider hängt System.CodeDom, sgen.exe und Legacy Tooling davon ab, dass sie da sind. Wenn sie als Referenzen verwendet werden, kann das Programm be very troublesome ausgeführt werden, wenn das Programm auf einem anderen Computer mit einer anderen Framework-Version ausgeführt wird.

Also schauen Sie sich die Baugruppen in der GAC zu wissen, was wirklich passiert zur Laufzeit passiert. Seit .NET 4.0 gibt es dort auch eine große Veränderung, jetzt lebt es in einem anderen Verzeichnis. Zuvor in c: \ windows \ assembly, jetzt in c: \ windows \ microsoft.net \ assembly. Und die sichtbarste Änderung, es hat nicht länger die Shell-Erweiterung, die Sie daran hindert, zu Dateien in diesem Verzeichnis zu navigieren. Sie können direkt durch die GAC-Ordnerstrukturen navigieren. Es ist ein kleines bisschen gefaltet, da Assemblys, die nicht verwalteten Code enthalten (wie mscorlib.dll) in einem separaten Verzeichnis gespeichert sind. Sehen Sie nach, Sie werden wenig Mühe haben, das Schema herauszufinden.

Die C: \ Windows \ Microsoft.NET \ Assembly \ GAC_MSIL \ System.Runtime \ v4.0_4.0.0.0__b03f5f7f11d50a3a \ System.Runtime.dll-Assembly, die Sie dort finden, ist in der Tat ziemlich leer. Vermutlich haben Sie jedoch das wichtigste Detail im Manifest verpasst. Es enthält ein Los der [TypeForwardedTo] Attribute.Ein Schnipsel von denen, die Sie dort finden:

[assembly: TypeForwardedTo(typeof(Action))] 
[assembly: TypeForwardedTo(typeof(Action<>))] 
[assembly: TypeForwardedTo(typeof(Action<,,,,,,,,,>))] 
[assembly: TypeForwardedTo(typeof(Action<,,,,,,,,,,>))] 
[assembly: TypeForwardedTo(typeof(Action<,,,,,,,,,,,>))] 
[assembly: TypeForwardedTo(typeof(Action<,,,,,,,,,,,,>))] 
[assembly: TypeForwardedTo(typeof(Action<,,,,,,,,,,,,,>))] 
[assembly: TypeForwardedTo(typeof(Action<,,,,,,,,,,,,,,>))] 
[assembly: TypeForwardedTo(typeof(Action<,,,,,,,,,,,,,,,>))] 
// etc, many more 

Vielleicht können Sie sehen, was jetzt los ist, hat System.Runtime.dll nicht enthalten überhaupt keinen Code. Es handelt sich um einen Adapter, der Typen von einer Baugruppe an eine andere weiterleitet. Die Desktopversion von .NET leitet Typen an mscorlib.dll, System.dll, System.ComponentModel.Composition und System.Core weiter.

"Die Desktop-Version" im vorherigen Satz ist der Schlüssel, der erklärt, warum dies getan wurde. Es gibt viele .NET Framework-Versionen, sie haben verschiedene Weiterleitungen in System.Runtime. Diese Adapter-Baugruppen erwerben Microsoft eine zusätzliche Ebene der Indirektion. Es hilft Ihnen, .NET-Code zu schreiben, der plattformunabhängig ist und denselben ohne Änderungen ausführt, egal ob Sie ihn auf dem Desktop, einer Store-App, im Browser mit Silverlight, auf der XBox-Spielekonsole oder auf einem Telefon ausführen. Obwohl die letzteren einen ziemlich anderen Rahmen haben, einen viel kleineren, der .NETCore genannt wird. Die Projektvorlage der Portable Class Library ist der Hauptnutznießer.

+0

Wow, das ist überwältigend! Ich nehme an, Xamarin nutzt diese Sprachprojektion ebenfalls aus? Vielen Dank für diese lange Antwort. Gibt es offizielle Dokumente, in denen ich mehr zu diesen Änderungen lesen kann? –

+1

Dies ist nicht dokumentiert, wo ich weiß. So etwas wird normalerweise in Blogs semi-dokumentiert, aber weder David Kean noch Mircea Trofin sind gewissenhafte Blogger. Ich habe das aus dem Studium der Referenzbaugruppen rekonstruiert, dauerte eine Weile. SO ist das fehlende Handbuch. –

+0

Ein PCL mit einem Verweis auf ".NET Portable Subset", der auf eine bestimmte Profile123-Untergruppe verweist, leitet wiederum Typen von Profile123 an eine bestimmte Bibliothek und Version auf dem Zielgerät weiter? –