Wie arbeite ich um log4net herum, indem ich publickeytoken immer wieder ändere?

99

Wir haben ein asp.net 4.0-Projekt, das einige Frameworks verwendet, die von log4net Version 1.2.10.0 abhängig sind. Heute habe ich versucht, ein neues Framework aufzunehmen, das von log4net Version 1.2.11.0 abhängig ist. Seitdem stecke ich fest:

log4net 1.2.10.0 hat publickeytoken = 1b44e1d426115821

log4net 1.2.11.0 hat publickeytoken = 669e0ddf0bb1aa2a

Da diese unterschiedlich sind, kann ich weder Assembly-Weiterleitungen (damit alle Frameworks dieselbe Version von log4net verwenden) noch Codebasis (damit nur das neue Framework Version 1.2.11.0 verwendet) über das Laufzeitelement in web.config verwenden.

Welche Möglichkeiten habe ich hier?

(und warum der Signalton log4net immer wieder publickeytokens zwischen Versionen ändert, da ich verstehe, dass ein verlorener Schlüssel der Grund für den Wechsel zwischen Version 1.2.9.0 und 1.2.10.0 war, haben sie den Schlüssel noch einmal verloren? Ich werde meine Dropbox freiwillig zur Verfügung stellen um es sicher zu halten, wenn sie es brauchen ...)

Bearbeiten: Ok, also hatten die log4net-Leute anscheinend die Idee, dass das Freigeben mit zwei Schlüsseln eine gute Idee ist, aber das bedeutet, dass jedes Framework, das Sie verwenden, sich darauf einigen muss, welche der beiden Varianten sie bevorzugen, oder diese Frameworks können nicht funktionieren nebeneinander in der gleichen Appdomain. Bin ich der einzige, der dies für eine schreckliche Idee hält? Wenn jeder das tun würde, würde alles zusammenbrechen, oder?

Edit2: Wie bereits erwähnt, verwende ich in meinem Geschäftscode nicht log4net, sondern mehrere Frameworks, die von 1.2.10.0 abhängen. Das Problem trat auf, als ich versuchte, ein neues Framework zu verwenden, das von 1.2.11.0 abhing (neuer Schlüssel) ), daher trifft die Antwort von Stefans nicht zu, da das neue Framework den neuen Schlüssel erwartet, nicht den alten

AndreasKnudsen
quelle
1
Meiner Meinung nach besteht der erste Fehler von Apache darin, die mit einem neuen Schlüssel signierten Binärdateien bereitzustellen: Der neue Schlüssel ist für die gepatchte / erweiterte Open Source-Version vorgesehen und sollte nicht unverändert verwendet werden. Der zweite Fehler ist, dass das Framework, von dem Sie sprechen, nur mit der neuen log4net-Signatur freigegeben wurde: Es sollte eine Version mit der alten Signatur vorhanden sein.
JoeBilly
6
Eigentlich sehen Sie sich die dritte Variante an: die, die die Genies bei SAP als Teil des Crystal Reports for Visual Studio-Pakets mit ihrem eigenen starken Namen neu kompiliert haben, und um die Sache noch schlimmer zu machen, haben sie sie in den GAC gesteckt, der sie erstellen wird Ihre Abhängigkeiten zwischen Maschinen sind ein Albtraum.
Jeremy Holovacs

Antworten:

65

So habe ich die Dinge mit Version 1.2.11.0 zum Laufen gebracht.

  1. Fluch Apache für das Ändern des Schlüssels an erster Stelle :)
  2. Laden Sie die mit dem alten Schlüssel signierte Version 1.2.11.0 herunter .
  3. Sortieren Sie Ihren eigenen Code, indem Sie alle direkten Verweise auf log4net (neuer Schlüssel) entfernen und durch einen Verweis auf die mit dem alten Schlüssel signierte Assembly ersetzen.
  4. Sortieren Sie alle abhängigen Assemblys aus, indem Sie dieses Segment in Ihre web / app.config aufnehmen
   <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" culture="neutral" />
                <bindingRedirect oldVersion="0.0.0.0-1.2.10.0"
                                 newVersion="1.2.11.0"/>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
David Christiansen
quelle
9
Das Herunterladen der mit dem alten öffentlichen Schlüssel signierten Version ist erforderlich, da es leider nicht möglich ist, eine verbindliche Umleitung zu einer Assembly mit einem anderen öffentlichen Schlüssel durchzuführen.
David Christiansen
2
Dies scheint aufgrund einer bahnbrechenden Änderung in 1.2.11.0 zu scheitern: netpl.blogspot.com/2012/03/…
Sydney
Hat jemand eine Lösung für die Probleme gefunden, die unter dem von @sydneyos erwähnten Link beschrieben werden, der die folgende Ausnahme verursacht:Method not found: 'Void log4net.Config.BasicConfigurator.Configure()'
Neo
Leider gibt es keine andere Lösung als ein Downgrade auf 1.2.10. (oder jede von Ihnen verwendete abhängige Assembly neu kompilieren).
bk0
1
Legen Sie die 1.2.10-Assembly in einem anderen Verzeichnis ab und verwenden Sie diese Konfiguration: '<dependentAssembly> <AssemblyIdentity name = "log4net" publicKeyToken = "1b44e1d426115821" culture = "neutral" /> <bindingRedirect oldVersion = "0.0.0.0-1.2.9.0 "newVersion =" 1.2.10.0 "/> <codeBase version =" 1.2.10.0 "href =" Resources \ log4net-oldkey \ log4net.dll "/> </ dependAssembly> '
Agile Jedi
27

Ich verwende die neueste Version von log4net, die ich über Nuget heruntergeladen habe. Für eine der von mir verwendeten Bibliotheken ist jedoch die alte Version erforderlich. Meine Probleme führten mich zu dieser Frage.

Das Problem mit den anderen Antworten ist, dass sie für alle Bindungen dieselbe DLL-Version verwenden. Ich möchte Funktionen in der neuen Version für alles andere als die Legacy-Abhängigkeit verwenden.

Um dies tun zu können, müssen Sie Folgendes tun:

  1. Beginnen Sie mit dem Download der alten Version (Version 1.2.11.0).
  2. Benennen Sie die heruntergeladene Binärdatei in um log4net.1.2.10.dll. Fügen Sie es in Ihr Startprojekt ein, wobei die Build-Aktion auf None"Kopieren, wenn neuer" gesetzt ist. Geben Sie hier die Bildbeschreibung ein
  3. Teilen Sie .NET mit, wo sich die alte Version befindet:

App.config

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
            <assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" />
            <codeBase version="1.2.10.0" href="log4net.1.2.10.dll" />
        </dependentAssembly>
    </assemblyBinding>
</runtime>

Die hrefAttribute geben an, wo sich die alte Version befindet. Daher verweisen alle anderen Anfragen nach log4net auf die neue Version.

jgauffin
quelle
4
Dies ist eine großartige Lösung, da Sie beide Versionen für Bibliotheken verwalten können, die auf beide verweisen.
SouthShoreAK
2
DANKE! Das hat mich gerettet. Ich musste das "In Ausgabeverzeichnis kopieren" in "Nicht kopieren" ändern, aber ansonsten funktionierte es wie ein Zauber!
Daniel Hedenström
3

Sie können eine Version von log4net 1.2.11.0 herunterladen, die mit dem alten Schlüssel signiert ist. Der Grund, warum der Schlüssel geändert wurde, wird in den häufig gestellten Fragen erläutert:

http://logging.apache.org/log4net/release/faq.html#two-snks

(Grundsätzlich ist der neue Schlüssel öffentlich verfügbar und aus irgendeinem Grund wollten sie den alten Schlüssel nicht in die Distribution aufnehmen. Mir ist nicht klar, warum sie den alten Schlüssel nicht nur öffentlich verfügbar gemacht haben.)

Stefan Egli
quelle
10
Aber wenn ich eine Drittanbieter-Bibliothek verwende, die an den neuen Schlüssel gebunden ist, stecke ich immer noch fest (richtig?). Es ist nicht meine Wahl, das neue log4net zu verwenden, es ist das Framework eines Drittanbieters. Ich kann nicht sehen, wie dieses Zeug nicht in jedermanns Gesicht explodieren wird, da immer mehr Frameworks log4net mit dem neuen Schlüssel verwenden
AndreasKnudsen
Das ist leider richtig. Ich denke, Sie müssen in Betracht ziehen, dass nicht alle Komponenten dieselbe Version von log4net verwenden ...
Stefan Egli
1
.... und wie würde ich das machen? Gibt es in .net einen Mechanismus zur Behandlung dieses Problems?
AndreasKnudsen
1

Ich weiß nicht, ob es für Ihren speziellen Fall geeignet ist oder nicht, aber Sie können eines der Frameworks neu kompilieren, sodass log4net mit demselben öffentlichen Schlüssel verwendet wird. In meinem Fall war es FluentNHibernate, das log4net 1.2.10 und Combres mit log4net 1.2.11 mit neuem Schlüssel verwendet. Ich habe log4net 1.2.11 heruntergeladen, mit altem Schlüssel signiert und Combress damit neu kompiliert. Nach dieser hinzugefügten Assembly-Bindungsumleitung von 1.2.10 auf 1.2.11 beginnt die Arbeit.

Alex
quelle
0

Dies funktioniert nicht unbedingt in allen Fällen, aber da das Projekt, das log4net verwendete, OSS war, habe ich die Quelle heruntergeladen, die widersprüchliche Version von log4net durch die von mir verwendete Version ersetzt und das Projekt neu erstellt. In meinem Fall war es Topshelf, daher habe ich jetzt eine Version der Topshelf-Assembly, die mit derselben Version von log4net erstellt wurde, die ich verwende, und jetzt kann ich problemlos auf beide verweisen.

Mark J Miller
quelle
0

Ich habe versucht, zu den oben angegebenen Links zu wechseln, aber anscheinend funktionieren alle Links auf der Apache-Site nicht. Dann habe ich Folgendes getan, um das Problem zu beheben:

Verwenden Sie Nuget in Ihrem Visual Studio, um die neueste Version von log4net (1.2.13.0) herunterzuladen und zu installieren. Der NuGet-Paketmanager lädt automatisch das gesamte log4net (1.2.11.0) herunter und aktualisiert es auf die neueste Version.

George Huang
quelle