-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
105 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ on: | |
push: | ||
branches: | ||
- main | ||
- feature/assembly-context | ||
tags: | ||
- v* | ||
pull_request: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
namespace TokenMagician; | ||
using System.Reflection; | ||
using System.Runtime.Loader; | ||
|
||
internal class ModuleAssemblyLoadContext : AssemblyLoadContext | ||
{ | ||
private readonly string _dependencyDirPath; | ||
|
||
public ModuleAssemblyLoadContext(string dependencyDirPath) | ||
{ | ||
_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)) | ||
{ | ||
Console.WriteLine($"Loading assembly {assemblyName.Name} from {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; | ||
Check warning on line 31 in src/TokenMagician/ModuleAssemblyLoadContext.cs GitHub Actions / 🛠️ Test PowerShell Module
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
using System.Management.Automation; | ||
using System.Reflection; | ||
using System.Runtime.Loader; | ||
|
||
namespace TokenMagician; | ||
|
||
/// <summary> | ||
/// A class that initializes the module when it is imported into the session. | ||
/// </summary> | ||
public class ModuleResolveEventHandler : IModuleAssemblyInitializer, IModuleAssemblyCleanup | ||
{ | ||
// Get the path of the dependency directory. | ||
// In this case we find it relative to the AlcModule.Cmdlets.dll location | ||
private static readonly string s_dependencyDirPath = Path.GetFullPath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!); | ||
|
||
private static readonly ModuleAssemblyLoadContext s_dependencyAlc = | ||
new ModuleAssemblyLoadContext(s_dependencyDirPath); | ||
public void OnImport() | ||
{ | ||
// This is called when the module is imported into the session | ||
// and can be used to initialize the module. | ||
Console.WriteLine("Module imported"); | ||
AssemblyLoadContext.Default.Resolving += ResolveAssembly; | ||
} | ||
|
||
public void OnRemove(PSModuleInfo module) | ||
{ | ||
// This is called when the module is removed from the session | ||
// and can be used to cleanup the module. | ||
Console.WriteLine("Module removed"); | ||
AssemblyLoadContext.Default.Resolving -= ResolveAssembly; | ||
} | ||
|
||
private static Assembly ResolveAssembly(AssemblyLoadContext defaultAlc, AssemblyName assemblyToResolve) | ||
{ | ||
// We only want to resolve the Alc.Engine.dll assembly here. | ||
// Because this will be loaded into the custom ALC, | ||
// all of *its* dependencies will be resolved | ||
// by the logic we defined for that ALC's implementation. | ||
// | ||
// Note that we are safe in our assumption that the name is enough | ||
// to distinguish our assembly here, | ||
// since it's unique to our module. | ||
// There should be no other AlcModule.Engine.dll on the system. | ||
if (!File.Exists(Path.Combine(s_dependencyDirPath, $"{assemblyToResolve.Name}.dll"))) | ||
{ | ||
Console.WriteLine($"Assembly {assemblyToResolve.Name} not found in {s_dependencyDirPath}"); | ||
return null; | ||
Check warning on line 48 in src/TokenMagician/ModuleResolveEventHandler.cs GitHub Actions / 🛠️ Test PowerShell Module
|
||
} | ||
|
||
// Allow our ALC to handle the directory discovery concept | ||
// | ||
// This is where Alc.Engine.dll is loaded into our custom ALC | ||
// and then passed through into PowerShell's ALC, | ||
// becoming the bridge between both | ||
return s_dependencyAlc.LoadFromAssemblyName(assemblyToResolve); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters