Forum: PC-Programmierung Problem mit dotnet-Assemblyverweisen


von Martin M. (mmc8801)


Lesenswert?

Hallo zusammen,

ich habe ein kleines Problem mit Assemblyverweisen.

Meine Anwendungsstruktur ist wie hier abgebildet:

http://www.bilderload.com/bild/10318/versionTF0UG.png

Das Problem ist die tools.dll, die ich in zwei verschiedenen Versionen 
(in unterschiedlichen Verzeichnissen) vorliegen habe. Dies kann leider 
auch nicht geändert werden und muß so bleiben.

Wenn ich aus der testapp.exe auf die worker.dll zugreife, benutzt diese 
interessanterweise die Version 1.0.0.0 der tools.dll.

Ich bräuchte es aber so, daß die testapp.exe wie gezeichnet die V1.0.0.0 
benutzt und die worker.dll die Version 2.0.0.0.

Im MSDN habe ich dazu folgendes gefunden:

********
Zur Laufzeit müssen sich Komponenten entweder im Ausgabepfad des 
Projekts oder im Globaler Assemblycache (GAC) befinden.
Wenn das Projekt einen Verweis auf ein Objekt enthält, der sich nicht an 
einem dieser Orte befindet, müssen Sie den
Verweis beim Erstellen des Projekts in den Ausgabepfad des Projekts 
kopieren. Die CopyLocal-Eigenschaft gibt an, ob
diese Kopie erstellt werden muss. Wenn der Wert True lautet, wird der 
Verweis beim Erstellen des Projekts in das
Projektverzeichnis kopiert. Wenn der Wert False ist, wird der Verweis 
nicht kopiert.

bzw.

Überprüfen, ob der Assemblyname bereits zuvor gebunden wurde. Ist dies 
der Fall, wird die zuvor geladene Assembly verwendet.
********

Habt ihr da einen Tip für mich?

Danke,
Martin

von Arc N. (arc)


Lesenswert?

Keine Lust nachzusehen wie das statisch funktioniert...
Wenn das auch dynamisch zur Laufzeit nachgeladen werden darf, geht's in 
etwa so:
1
Assembly asm = Assembly.LoadFile(fileName);
2
// oder mit Assembly.Load("Test, Version=1.2.3.4, PublicToken=1234...")
3
Type asmType = asm.GetType("Namespace.TypeName");
4
TypeName instance = Activator.CreateInstance(asmType) as TypeName;

von Martin M. (mmc8801)


Lesenswert?

Hallo Arc,

danke für die Info, aber dynamisch nachladen geht leider nicht da durch 
"Late Binding" kein Intellisense bzw. Überprüfung der Methodenaufrufe 
etc. durch den Compiler möglich ist...

Gruß,
Martin

von MaWin (Gast)


Lesenswert?

Baust du wirklich eine DotNET Applikation, also die geschasste Antwort 
von Micrsoft auf Java, (auch von C++ mit grausamem 'managed code' aus 
verwendbar)
oder bist du nur auf den Namen des Visual Studios reingefallen ?

Echtes DotNET verwendet das .NET Runtime Framework CLI, das unterstützt 
Assemblies aus Manifest und solange die public key token deiner 
tools.dll unterschiedlich sind, werden auch unterschiedliche DLLs 
verwendet.

Für mich klingen deine Probleme also eher danach, als ob du eine 
einfache alte Win32 Anwendung schreibst. Vonwegen DotNET. Unter Win32 
geht es noch einfach, das Problem aufzulösen: Benenne eine tools.dll 
einfach um.

von Martin M. (mmc8801)


Lesenswert?

Ja das ist wirklich .net, der Unterschied zwischen Win32 und .net ist 
mir durchaus bewußt.

Das was du schreibst funktioniert IMHO aber nur wenn die Assemblies im 
GAC liegen, denn im bin-Verzeichnis (in dem meine Assemblies momentan 
liegen) kann ja (wegen NTFS) von jeder Datei(name) nur ein Exemplar 
liegen.

Das Laden eines Assemblies aus einem anderen (Sub-)Pfad (z.B. 
c:\bin\subfolder) geht meines Wissens nicht; wenn ich den Verweis 
entsprechend einbinde, kann ich zwar kompilieren; zur Laufzeit kommt 
aber eine Exception dass er das Assembly nicht findet.

"Lokale Kopie = True" löst das Problem, aber auch nur indem es das 
betreffende Assembly in meinen bin-Ordner kopiert.

Gruß,
Martin

von remmy (Gast)


Lesenswert?

Es ist also so, dass sich in den beiden Tool.dlls gleiche Objekte
befinden ? Da steht die Frage im Raum, wie die Runtime, falls sie
beide laden soll, die Objekttypen unterscheiden soll.

Als Beispiel : in beiden Dlls gibts eine worker.haus Klasse.

Du verlangst also, dass wenn in der Applikation beim Aufruf
... new worker.haus() die RT die Klasse aus der Version 1...
verwendet und beim selben Aufruf in der worker.dll die Klasse aus der
Version 2.

Naja, das ist ja noch nicht so ganz das Problem, aber welche
Version soll die Applikation bei einem Aufruf einer Methode in der 
worker.dll von worker.haus verwendet werden ?

z.B. Foo(worker.haus obj); ?

von Martin M. (mmc8801)


Lesenswert?

Ja in beiden tools.dll sind die gleichen Objekte, Methoden usw., nur 
halt unterschiedliche Versionen. Das Interface bleibt dabei immer gleich 
(abwärtskompatibel).

Deine Frage verstehe ich leider nicht ganz.

Müsste das nicht die Methode tools.haus sein?

Martin

von Arc N. (arc)


Lesenswert?

Martin M. schrieb:
> Ja in beiden tools.dll sind die gleichen Objekte, Methoden usw., nur
> halt unterschiedliche Versionen. Das Interface bleibt dabei immer gleich
> (abwärtskompatibel).
>
> Deine Frage verstehe ich leider nicht ganz.
>
> Müsste das nicht die Methode tools.haus sein?
>
> Martin

Dann geht das ganze aber auch dynamisch:
Ein Interface, was dann in den Klassen der Tools.dll implementiert wird.

von remmy (Gast)


Lesenswert?

@Martin M

Ja, sorry : tools.haus.

Das dynamische Laden bring nur was, wenn in der testapp.exe und
und in der worker.dll das gleiche Assembly (geiche version) geladen
wird. Egal ob 1.0 oder 2.0. Ansonsten wieder dasselbe Problem mit
gleichen Klassen mit unterschiedlicher Version.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.