-
Notifications
You must be signed in to change notification settings - Fork 927
/
Copy pathAssemblyBindingRedirect.cs
86 lines (78 loc) · 2.61 KB
/
AssemblyBindingRedirect.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*
* Copyright (c) 2017-Present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
namespace React.MSBuild
{
/// <summary>
/// Hacks around the fact that it's not possible to do assembly binding redirects in MSBuild.
///
/// https://github.com/Microsoft/msbuild/issues/1309
/// http://blog.slaks.net/2013-12-25/redirecting-assembly-loads-at-runtime/
/// </summary>
public static class AssemblyBindingRedirect
{
/// <summary>
/// Redirects that have been configured
/// </summary>
private static readonly Dictionary<string, Version> _redirects = new Dictionary<string, Version>();
static AssemblyBindingRedirect()
{
// This is in a static constructor because it needs to run as early as possible
ConfigureRedirect("JavaScriptEngineSwitcher.Core");
AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly;
}
/// <summary>
/// Enables assembly binding redirects
/// </summary>
public static void Enable()
{
// Intentionally empty. This is just meant to ensure the static constructor
// has run.
}
/// <summary>
/// Configures a redirect for the specified assembly. Redirects to the version in the bin directory.
/// </summary>
/// <param name="name">Name of the assembly to redirect</param>
private static void ConfigureRedirect(string name)
{
var currentAssemblyPath = Assembly.GetExecutingAssembly().Location;
var redirectAssemblyPath = Path.Combine(
Path.GetDirectoryName(currentAssemblyPath),
name + ".dll"
);
try
{
var realAssembly = Assembly.LoadFile(redirectAssemblyPath);
var version = realAssembly.GetName().Version;
_redirects[name] = version;
}
catch (Exception ex)
{
Trace.WriteLine("Warning: Could not determine version of " + name + " to use! " + ex.Message);
}
}
/// <summary>
/// Overrides assembly resolution to redirect if necessary.
/// </summary>
private static Assembly ResolveAssembly(object sender, ResolveEventArgs args)
{
var requestedAssembly = new AssemblyName(args.Name);
if (_redirects.ContainsKey(requestedAssembly.Name) && requestedAssembly.Version != _redirects[requestedAssembly.Name])
{
requestedAssembly.Version = _redirects[requestedAssembly.Name];
return Assembly.Load(requestedAssembly);
}
return null;
}
}
}