Laden...

BinaryReader um Bibliothek zu lesen

Erstellt von filmee24 vor 10 Jahren Letzter Beitrag vor 10 Jahren 843 Views
F
filmee24 Themenstarter:in
51 Beiträge seit 2011
vor 10 Jahren
BinaryReader um Bibliothek zu lesen

Hallo,
ich versuche eine Assembly aus einem String zu laden und eine Instanz zu erstellen.
Zum Testen hab ich die StringBuilder Klasse und Assembly genommen.
Die Assembly wird geladen, aber es erstellt mir keine Instanz des Objektes:

Code:

var br = new BinaryReader(new FileStream(typeof(StringBuilder).Assembly.Location, FileMode.Open));
            byte[] data = br.ReadBytes((int)br.BaseStream.Length);
            br.Close();

            var assembly = Assembly.Load(data);
            var sb = assembly.CreateInstance("StringBuilder") as StringBuilder;

was mache ich Falsch?

Vielen Dank

C. Anders

2.080 Beiträge seit 2012
vor 10 Jahren

Guck dir mal die Stichworte IDisposable und using an.

FileStream hat IDisposable implementiert und sollte nach der Verwendung auch entsprechend disposed werden.
Das gleiche gilt für den BinaryReader. Hier rufst du die Dispose-Methode zwar indirekt über die Close-Methode auf, allerdings wäre es besser, alles, was IDisposable implementiert hat, in einem using-Block zu verwenden, denn danach werden die Ressourcen garantiert (auch bei Exceptions) frei gegeben.

Warum die Instanz nicht erstellt wird:
Ich vermute einfach mal, weil die StringBuilder-Klasse nicht in der Assembly liegt, die liegt in mscorlib.dll
Hab grad bemerkt, dass du die Assembly der Klasse ja vom Typ bekommst. Den nachfolgenden Test kannst du aber trotzdem mal ausprobieren.

Erstelle doch mal testweise eine DLL, wo du einen eigenen Typ drin liegen hast und lasse dir davon eine Instanz erstellen.

Wenn ich dein Vorhaben aber richtig verstanden habe, dann geht das alles auch viel einfacher, in Gewusst wie: Laden und Entladen von Assemblys (C# und Visual Basic) nach zu lesen.

PS: Ok, hab den Fehler.

Du brauchst den vollständigen Namen des Typs, das meint auch den Namespace.
Außerdem hättest du bei deinem Code schon in der ersten Zeile eine Exception erhalten müssen, da Windows den Zugriff auf die mscorlib.dll nicht zu lässt, es ist nur lesender Zugriff erlaubt und das musst du explizit über einen weiteren Parameter im Konstruktor angeben.

So funktioniert es auf jeden Fall und kurz:

var sourceType = typeof(StringBuilder);
var assembly = Assembly.LoadFile(sourceType.Assembly.Location);
var stringBuilderType = assembly.GetType(sourceType.FullName);
var obj = Activator.CreateInstance(stringBuilderType) as StringBuilder;

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

16.842 Beiträge seit 2008
vor 10 Jahren

FileStream hat IDisposable implementiert und sollte nach der Verwendung auch entsprechend disposed werden.
Das gleiche gilt für den BinaryReader. Hier rufst du die Dispose-Methode zwar indirekt über die Close-Methode auf, allerdings wäre es besser, alles, was IDisposable implementiert hat, in einem using-Block zu verwenden

Das stimmt so nicht.
In diesem Fall wäre das sogar ein Fehler, den auch FxCop anmäkeln würde und bei nicht ganz so sicheren Dispose-Implementierungen sogar eine Exception werfen kann.

Generell sollte man using() verwenden, ja - aber korrekt.
Bei Streams o.ä. erfolgt ein Disposing in der Regel "nach oben". Das heisst, dass der Dispose von BinaryReader intern auch den Dispose von FileStream ausführt.
Close wiederum tut nichts anderes - beim BinaryReader - als disposen.

"Vorbildlich" wäre hier also


var fileStream = ...
using(var binaryReader = new BinaryReader( fileStream, ....)
{
    // ....
}

Weil das Dispose - hier - aber sehr defensiv entwickelt wurde wäre


using(var fileStream = ... )
using(var binaryReader = new BinaryReader( fileStream, ....)
{
    // ....
}

auch kein Problem; kann dem ein oder anderen sogar besser gefallen; nur dem FxCop eben nicht.

Wenn also die data-Zuweisung im Code des Threaderstellers kein Fehler wirft ist der Code korrekt und auch "sicher".