Laden...

[gelöst] Verwendete Version einer DLL zur Laufzeit wechseln

Erstellt von Slaughter vor 9 Jahren Letzter Beitrag vor 9 Jahren 3.293 Views
S
Slaughter Themenstarter:in
61 Beiträge seit 2008
vor 9 Jahren
[gelöst] Verwendete Version einer DLL zur Laufzeit wechseln

Hallo,

**wie muss ich Visual Studio und die app.config konfigurieren, damit das Umschalten von Drittanbieter API DLL (V1.0) auf API DLL (V2.0) zur Laufzeit funktioniert? **

Zur Erläuterung:

Ich habe eine Anwendung entwickelt, welche in drei Schichten aufgeteilt ist.

  1. Data Layer (Zwei Repository Projekte)
  2. Service Layer
  3. User Experience Layer
    Jede Schicht enthält wenigstens ein eigenständiges .NET Projekt, welche in einer .NET Solution zusammengefasst sind.

Im Data Layer befindet sich ein Repository mit einer Referenz auf eine API DLL, die sich in der Version 1.0 befindet. Über die API DLL greife ich auf ein System eines Drittanbieters zu (ebenfalls in Version 1.0).

Für das Drittanbietersystem gibt es nun eine Version 2.0 und ebenso für die API DLL, warum ich ein neues Repository Projekt erstellt habe, welches die API DLL in der Version 2.0 enthält.

Ich habe mein Programm im User Experience Layer nun so gestaltet, dass ich einen Parameter an den Service Layer übergebe, der entweder das bestehende Repository Projekt mit der API DLL Version 1.0 oder das neue Repository mit der API DLL Version 2.0 instanziert und zum Datenabgleich verwendet. Somit kommt also im DataLayer ein zweites Repository Projekt hinzu. Beide Repositories implementieren das selbe Interface.

Aktuell werden die DLLs V1.0 und V2.0 immer in den "bin" Ordner des User Experience Projekts kopiert und somit immer eine Version der DLLs überschrieben, so dass nur ein Repository funktioniert.

Freundliche Grüße

Slaughter

16.807 Beiträge seit 2008
vor 9 Jahren

Im Prinzip ist das ein Pluginverhalten und kann nicht in der Config konfiguriert werden.
Sowas geht aber auch via LateBinding und Reflection.

MEF wäre wohl der richtige Ansatzpunkt für solch einen Funktionswunsch.
Es sollte aber klar sein, dass dies keine 1+1 Aufgabe ist.

Willst Du ein Live-Switch musst Du Dich auch noch mit der AppDomain auseinander setzen, da sich Assemblies nicht entladen lassen.

1.361 Beiträge seit 2007
vor 9 Jahren

Hi Slaughter,

Anscheinend hast du in deinem Code schon die Möglichkeit unterschiedliche Versionen dieser Library gleichzeitig zu nutzen.

Machst du das über extern alias?

Wenn ja, dann sollte dein einziges Problem am Ende nur noch sein, dass die Bibliotheken vom Dateinamen her gleich heißen ("wasAuchImmer.dll"), du aber hiervon zwei Versionen mitliefern willst.
Du kann abhängig von der Version über die app.config auf verschiedene Pfade verweisen: Multiple Assemblies with the Same Name

<?xml version="1.0"?>
<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
            <assemblyIdentity name="wasAuchImmer" /> 
            <codeBase version="1.0.0.0" href="lib/v1/wasAuchImmer.dll"/>
            <codeBase version="2.0.0.0" href="lib/v2/wasAuchImmer.dll"/>
        </dependentAssembly>
      </assemblyBinding>   
   </runtime>
</configuration>

beste Grüße
zommi

4.221 Beiträge seit 2005
vor 9 Jahren

Die Versions-Dll NICHT im Bin ablegen sondern in einem Unterverzeichnis dessen....

Häng dich in AppDomain.CurrentDomain.AssemblyResolve - Event

Dann kannst Du entweder das eine oder das andere dll zurückliefern.

Aber Achtung: Einmal geladen ist geladen ! das kriegst Du nicht mehr raus.

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

S
Slaughter Themenstarter:in
61 Beiträge seit 2008
vor 9 Jahren

Hallo und danke für Eure Antworten, aber es funktioniert leider noch nicht ganz.

Ich versuche aktuell den Ansatz von "zommi" und verwende in der Klassen der Repository Projekte (1.0 und 2.0) den externen Alias, den ich bei den Referenzeigenschaften definiert habe. Ansonsten steht bei den Referenzeigenschaften "Copy Local" auf "False" und "Specific Version" auf "False", wo ich nicht sicher bin, ob das richtig ist.

Für die DLLs habe ich im Dateisystem unterhalb der Solution einen Ordner "lib" angelegt. Darin befinden sich ein Ordner "v1" und ein Ordner "v2" . In diesen Ordnern liegt die jeweilige DLL. Ich weiß nicht, ob diese Ablagestelle richtig ist. Oder ob ich die DLLs in Unterordnern im "bin" Verzeichnis des Commandline Projekts ablegen muss.

In der app.config des Commandline Projektes habe ich folgendes definiert:

 
<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="ThirdParty.dll" publicKeyToken="xyz" />
        <codeBase version="1.0.0.0" href="lib/v1/ThirdParty.dll"/>
        <codeBase version="2.0.0.0" href="lib/v2/ThirdParty.dll"/>
      </dependentAssembly>
</runtime>

Der Aufruf mit der ThirdParty.dll V2.0 funktioniert aktuell aber die mit der ThirdParty.dll V1.0 nicht. Hier bekomme ich folgende Fehlermeldung:

Fehlermeldung:
Could not load file or assembly 'ThirdParty, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xyz' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference.

Ich hoffe, Ihr könnt mir weiterhelfen.

Slaughter

S
Slaughter Themenstarter:in
61 Beiträge seit 2008
vor 9 Jahren

Hallo,

ich habe das Problem gefunden und die Lösug funktioniert jetzt.

  1. Im Namen bei assemblyIdentity hatte ich "ThirdParty.dll" eingetragen. Dort darf aber nur "ThirdParty" stehen.
  2. Die Pfade habe ich einfach vollqualifiziert eingetragen. Das geht so:
<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="ThirdParty" publicKeyToken="xyz" />
        <codeBase version="1.0.0.0" href="FILE://C:/myDevelopment/lib/v1/ThirdParty.dll"/>
        <codeBase version="2.0.0.0" href="FILE://C:/myDevelopment/lib/v2/ThirdParty.dll"/>
      </dependentAssembly>
</runtime>

Vielen Dank an alle die mich hier unterstützt haben.

Slaughter