Antwort

2

Es ist heute nicht direkt möglich, aber wir denken über Möglichkeiten nach, dies zu erreichen. Können Sie bitte ein Problem auf https://github.com/Azure/azure-webjobs-sdk-script/issues öffnen, um sicherzustellen, dass Ihr spezifisches Szenario betrachtet wird? Vielen Dank!

+1

neues verwandtes Problem: Geben Sie Bindung Umleitungen für CSX mehr dll # 1239 https://github.com/Azure/azure-webjobs-sdk-script/issues/1239 –

8

Angenommen, Sie verwenden die neueste (Juni'17) Visual Studio 2017-Funktion Tooling, leitete ich eine einigermaßen vernünftige config-basierte Lösung für diese nach einem Codeschnipsel von npiasecki über auf Issue #992.

Es wäre ideal, wenn dies über das Framework gemanagt wird, aber zumindest konfigurationsgesteuert ist, haben Sie ein bisschen mehr Änderungsisolation. Ich nehme an, Sie könnten auch einige Pre-Build-Schritte oder T4-Templating verwenden, die die Versionen der Nugets im Projekt (und deren Abhängigkeiten) abgleichen, bevor Sie diese Konfiguration oder den Code generieren.

So ist die Kehrseite ..

.. wird mit sich zu erinnern, die BindingRedirects Config zu aktualisieren, wenn Sie die NuGet-Paket aktualisieren (ist dies oft ein Problem in app.configs sowieso). Möglicherweise haben Sie auch ein Problem mit der konfigurationsgesteuerten Lösung, wenn Sie Newtonsoft umleiten müssen.

In unserem Fall verwendeten wir das neue Azure Fluent NuGet, das von einer älteren Version Microsoft.IdentityModel.Clients.ActiveDirectory abhängig war als die Version der normalen ARM-Verwaltungsbibliotheken, die nebeneinander in einer bestimmten Funktion verwendet wurden.

local.settings.json
{ 
    "IsEncrypted": false, 
    "Values": { 
     "BindingRedirects": "[ { \"ShortName\": \"Microsoft.IdentityModel.Clients.ActiveDirectory\", \"RedirectToVersion\": \"3.13.9.1126\", \"PublicKeyToken\": \"31bf3856ad364e35\" } ]" 
    } 
} 
FunctionUtilities.cs
using Newtonsoft.Json; 
using Newtonsoft.Json.Linq; 
using System; 
using System.Globalization; 
using System.Linq; 
using System.Reflection; 

namespace Rackspace.AzureFunctions 
{ 
    public static class FunctionUtilities 
     { 
      public class BindingRedirect 
      { 
       public string ShortName { get; set; } 
       public string PublicKeyToken { get; set; } 
       public string RedirectToVersion { get; set; } 
      } 

      public static void ConfigureBindingRedirects() 
      { 
       var config = Environment.GetEnvironmentVariable("BindingRedirects"); 
       var redirects = JsonConvert.DeserializeObject<List<BindingRedirect>>(config); 
       redirects.ForEach(RedirectAssembly); 
      } 

      public static void RedirectAssembly(BindingRedirect bindingRedirect) 
      { 
       ResolveEventHandler handler = null; 

       handler = (sender, args) => 
       { 
        var requestedAssembly = new AssemblyName(args.Name); 

        if (requestedAssembly.Name != bindingRedirect.ShortName) 
        { 
         return null; 
        } 

        var targetPublicKeyToken = new AssemblyName("x, PublicKeyToken=" + bindingRedirect.PublicKeyToken) 
         .GetPublicKeyToken(); 
        requestedAssembly.Version = new Version(bindingRedirect.RedirectToVersion); 
        requestedAssembly.SetPublicKeyToken(targetPublicKeyToken); 
        requestedAssembly.CultureInfo = CultureInfo.InvariantCulture; 

        AppDomain.CurrentDomain.AssemblyResolve -= handler; 

        return Assembly.Load(requestedAssembly); 
       }; 

       AppDomain.CurrentDomain.AssemblyResolve += handler; 
      } 
     } 
    } 
+0

Vielen Dank für diese geladen werden. Dies ist für die meisten nugget-Projekte ziemlich notwendig. Hoffentlich werden sie das bald angehen. – Grapes

+1

Für alle, die Schwierigkeiten damit haben: Wenn Sie mehr als eine Version haben, die neu gebunden werden muss, müssen Sie die Zeile AppDomain.CurrentDomain.AssemblyResolve - = handler; Da dies bedeutete, nur die erste Version wurde gefunden, umgeleitet wurde. – bech

1

durch die akzeptierte Antwort Inspired ich dachte, ich würde eine allgemeinere man tun, die auch berücksichtigt Upgrades erfolgt.

Es ruft alle Baugruppen ab, sortiert sie absteigend, um die neueste Version zu erhalten, und gibt dann die neueste Version zurück. Ich rufe das selbst in einem statischen Konstruktor auf.

public static void RedirectAssembly() 
{ 
    var list = AppDomain.CurrentDomain.GetAssemblies().OrderByDescending(a => a.FullName).Select(a => a.FullName).ToList(); 
    AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => 
    { 
     var requestedAssembly = new AssemblyName(args.Name); 
     foreach (string asmName in list) 
     { 
      if (asmName.StartsWith(requestedAssembly.Name + ",")) 
      { 
       return Assembly.Load(asmName); 
      } 
     } 
     return null; 
    }; 
}