Thursday, November 13, 2014

Binding redirects at runtime

Hopfully the C# audience can read this F#, but this is how you would do it =)
// https://dotnetfiddle.net/UnS2vU
printfn "starting up"
open System
open System.Reflection

let RedirectAssembly shortName (targetVersion : Version) publicKeyToken = 
    let rec onResolveEvent = new ResolveEventHandler( fun sender evArgs ->
        let requestedAssembly = 
            AssemblyName(evArgs.Name)
        if requestedAssembly.Name <> shortName 
        then 
            printfn "redirect firing for %s" requestedAssembly.Name; Unchecked.defaultof<Assembly>
        else 
            printfn 
                "Redirecting assembly load of %s ,\tloaded by %s" 
                evArgs.Name 
                (if evArgs.RequestingAssembly = null then 
                     "(unknown)"
                 else 
                     evArgs.RequestingAssembly.FullName)
            requestedAssembly.Version <- targetVersion
            requestedAssembly.SetPublicKeyToken (AssemblyName(sprintf "x, PublicKeyToken=%s" publicKeyToken).GetPublicKeyToken())
            requestedAssembly.CultureInfo <- System.Globalization.CultureInfo.InvariantCulture
            AppDomain.CurrentDomain.remove_AssemblyResolve(onResolveEvent)
            Assembly.Load (requestedAssembly)
            )
    AppDomain.CurrentDomain.add_AssemblyResolve(onResolveEvent)
    
// sample usage
RedirectAssembly "FSharp.Core" (Version("4.3.1.0")) "b03f5f7f11d50a3a"