mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
84 lines
2.9 KiB
C#
84 lines
2.9 KiB
C#
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT License.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Management.Automation;
|
|
using System.Reflection;
|
|
using System.Runtime.Loader;
|
|
|
|
namespace Test.Isolated.Init
|
|
{
|
|
internal class CustomLoadContext : AssemblyLoadContext
|
|
{
|
|
private readonly string _dependencyDirPath;
|
|
|
|
public CustomLoadContext(string dependencyDirPath)
|
|
: base("MyCustomALC", isCollectible: false)
|
|
{
|
|
_dependencyDirPath = dependencyDirPath;
|
|
}
|
|
|
|
protected override Assembly Load(AssemblyName assemblyName)
|
|
{
|
|
// We do the simple logic here of looking for an assembly of the given name
|
|
// in the configured dependency directory.
|
|
string assemblyPath = Path.Combine(_dependencyDirPath, $"{assemblyName.Name}.dll");
|
|
|
|
if (File.Exists(assemblyPath))
|
|
{
|
|
// The ALC must use inherited methods to load assemblies.
|
|
// Assembly.Load*() won't work here.
|
|
return LoadFromAssemblyPath(assemblyPath);
|
|
}
|
|
|
|
// For other assemblies, return null to allow other resolutions to continue.
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public class Init : IModuleAssemblyInitializer, IModuleAssemblyCleanup
|
|
{
|
|
private static readonly CustomLoadContext s_context;
|
|
private static readonly HashSet<string> s_moduleAssemblies;
|
|
|
|
static Init()
|
|
{
|
|
string dependencyDirPath = Path.Combine(Path.GetDirectoryName(typeof(Init).Assembly.Location), "Dependencies");
|
|
s_context = new CustomLoadContext(dependencyDirPath);
|
|
s_moduleAssemblies = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
|
{
|
|
"Test.Isolated.Nested",
|
|
"Test.Isolated.Root"
|
|
};
|
|
}
|
|
|
|
public void OnImport()
|
|
{
|
|
// Add the Resolving event handler here.
|
|
AssemblyLoadContext.Default.Resolving += ResolveAlcEngine;
|
|
}
|
|
|
|
public void OnRemove(PSModuleInfo psModuleInfo)
|
|
{
|
|
// Remove the Resolving event handler here.
|
|
AssemblyLoadContext.Default.Resolving -= ResolveAlcEngine;
|
|
}
|
|
|
|
private static Assembly ResolveAlcEngine(AssemblyLoadContext defaultAlc, AssemblyName assemblyToResolve)
|
|
{
|
|
// We only want to resolve our module assemblies here.
|
|
if (s_moduleAssemblies.Contains(assemblyToResolve.Name))
|
|
{
|
|
// This is where the nested module 'Test.Isolated.Nested.dll' and the root module 'Test.Isolated.Root.dll'
|
|
// gets loaded into our custom ALC and then passed through into PowerShell's ALC.
|
|
return s_context.LoadFromAssemblyName(assemblyToResolve);
|
|
}
|
|
|
|
// Let the resolution chain continue for other assemblies.
|
|
return null;
|
|
}
|
|
}
|
|
}
|