AssemblyResolveScope: stable binding redirect calculation

This commit is contained in:
Friedrich von Never 2023-08-08 22:57:50 +02:00
parent 04aca012c9
commit 2e49fd2086
2 changed files with 27 additions and 38 deletions

View file

@ -1,22 +1,22 @@
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Linq;
using PascalABCCompiler.SemanticTree;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics.SymbolStore;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.Security;
using System.Runtime.Versioning;
using System.Security;
using System.Text;
using System.Threading;
using NETGenerator;
using PascalABCCompiler.NetHelper;
using PascalABCCompiler.SemanticTree;
namespace PascalABCCompiler.NETGenerator
{
@ -1240,7 +1240,7 @@ namespace PascalABCCompiler.NETGenerator
{
if (IsDotnet5() || IsDotnetNative()) return;
var appConfigPath = targetAssemblyPath + ".config";
AppConfigUtil.UpdateAppConfig(resolveScope.BindingRedirects, appConfigPath);
AppConfigUtil.UpdateAppConfig(resolveScope.CalculateBindingRedirects(), appConfigPath);
}
private void AddSpecialInitDebugCode()

View file

@ -16,14 +16,24 @@ namespace PascalABCCompiler.NetHelper
private readonly Dictionary<string, Assembly> _assembliesByName = new Dictionary<string, Assembly>();
private readonly Dictionary<string, Assembly> _assembliesByPath = new Dictionary<string, Assembly>();
/// <remarks>Key = the resulting assembly, value = the highest version of the redirected assembly.</remarks>
private readonly Dictionary<AssemblyName, AssemblyName> _assemblyNameOverrides =
new Dictionary<AssemblyName, AssemblyName>();
public ICollection<AssemblyName> CalculateBindingRedirects()
{
var redirectedAssemblies = new HashSet<string>();
foreach (var assembly in _assembliesByName.Values)
{
foreach (var referenceName in assembly.GetReferencedAssemblies())
{
var shortName = referenceName.Name;
if (_assembliesByName.TryGetValue(shortName, out var referenceAssembly)
&& referenceAssembly.GetName().Version != referenceName.Version)
{
redirectedAssemblies.Add(shortName);
}
}
}
public ICollection<AssemblyName> BindingRedirects => _assemblyNameOverrides
.Where(kv => kv.Key.Version != kv.Value.Version)
.Select(kv => kv.Key)
.ToList();
return redirectedAssemblies.Select(a => _assembliesByName[a].GetName()).ToList();
}
public AssemblyResolveScope(AppDomain appDomain)
{
@ -50,7 +60,7 @@ namespace PascalABCCompiler.NetHelper
_appDomain.AssemblyResolve -= OnAssemblyResolve;
}
private Assembly ResolveAssembly(ResolveEventArgs args)
private Assembly OnAssemblyResolve(object obj, ResolveEventArgs args)
{
var requestedName = new AssemblyName(args.Name);
if (_assembliesByName.TryGetValue(requestedName.Name, out var assembly))
@ -73,26 +83,5 @@ namespace PascalABCCompiler.NetHelper
}
return null;
}
private Assembly OnAssemblyResolve(object obj, ResolveEventArgs args)
{
var assembly = ResolveAssembly(args);
if (assembly != null)
{
var resolvedName = assembly.GetName();
var requestingName = new AssemblyName(args.Name);
if (_assemblyNameOverrides.TryGetValue(resolvedName, out var overriddenName))
{
if (overriddenName.Version < requestingName.Version)
_assemblyNameOverrides[resolvedName] = requestingName;
}
else
{
_assemblyNameOverrides.Add(resolvedName, requestingName);
}
}
return assembly;
}
}
}