/// <summary>
/// The handler for the Resolving event
/// </summary>
private Assembly Resolve(AssemblyLoadContext loadContext, AssemblyName assemblyName)
{
// Probe the assembly cache
Assembly asmLoaded;
if (TryGetAssemblyFromCache(assemblyName, out asmLoaded))
return asmLoaded;
// Prepare to load the assembly
lock (s_syncObj)
{
// Probe the cache again in case it's already loaded
if (TryGetAssemblyFromCache(assemblyName, out asmLoaded))
return asmLoaded;
// Search the specified assembly in probing paths, and load it through 'LoadFromAssemblyPath' if the file exists and matches the requested AssemblyName.
// If the CultureName of the requested assembly is not NullOrEmpty, then it's a resources.dll and we need to search corresponding culture sub-folder.
bool isAssemblyFileFound = false, isAssemblyFileMatching = false;
string asmCultureName = assemblyName.CultureName ?? string.Empty;
string asmFilePath = null;
for (int i = 0; i < _probingPaths.Count; i++)
{
string probingPath = _probingPaths[i];
string asmCulturePath = Path.Combine(probingPath, asmCultureName);
for (int k = 0; k < _extensions.Length; k++)
{
string asmFileName = assemblyName.Name + _extensions[k];
asmFilePath = Path.Combine(asmCulturePath, asmFileName);
if (File.Exists(asmFilePath))
{
isAssemblyFileFound = true;
AssemblyName asmNameFound = GetAssemblyName(asmFilePath);
if (IsAssemblyMatching(assemblyName, asmNameFound))
{
isAssemblyFileMatching = true;
break;
}
}
}
if (isAssemblyFileFound && isAssemblyFileMatching)
{
break;
}
}
// We failed to find the assembly file; or we found the file, but the assembly file doesn't match the request.
// In this case, return null so that other Resolving event handlers can kick in to resolve the request.
if (!isAssemblyFileFound || !isAssemblyFileMatching)
{
return null;
}
asmLoaded = asmFilePath.EndsWith(".ni.dll", StringComparison.OrdinalIgnoreCase)
? loadContext.LoadFromNativeImagePath(asmFilePath, null)
: loadContext.LoadFromAssemblyPath(asmFilePath);
if (asmLoaded != null)
{
// Add the loaded assembly to the cache
s_assemblyCache.TryAdd(assemblyName.Name, asmLoaded);
}
}
// Raise AssemblyLoad event
OnAssemblyLoaded(asmLoaded);
return asmLoaded;
}