Skip to content

Commit 29940aa

Browse files
Fix plugin dependency loading by using LoadFromAssemblyPath and modernize PluginLoadContext (#37)
* Initial plan * Fix plugin dependency loading by using LoadFromAssemblyPath and modernize PluginLoadContext Co-authored-by: matt-goldman <[email protected]> --------- Co-authored-by: Copilot <[email protected]> Co-authored-by: matt-goldman <[email protected]>
1 parent b613aa1 commit 29940aa

File tree

4 files changed

+27
-20
lines changed

4 files changed

+27
-20
lines changed

src/Blake.BuildTools/Utils/PluginLoadContext.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,9 @@ namespace Blake.BuildTools.Utils;
77
/// A custom AssemblyLoadContext that provides isolated plugin loading with dependency resolution.
88
/// Each plugin gets its own load context to avoid dependency conflicts.
99
/// </summary>
10-
internal class PluginLoadContext : AssemblyLoadContext
10+
internal class PluginLoadContext(string pluginPath) : AssemblyLoadContext(isCollectible: true)
1111
{
12-
private readonly AssemblyDependencyResolver _resolver;
13-
14-
public PluginLoadContext(string pluginPath) : base(isCollectible: true)
15-
{
16-
_resolver = new AssemblyDependencyResolver(pluginPath);
17-
}
12+
private readonly AssemblyDependencyResolver _resolver = new(pluginPath);
1813

1914
protected override Assembly? Load(AssemblyName assemblyName)
2015
{

src/Blake.BuildTools/Utils/PluginLoader.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,7 @@ private static void LoadPluginDLLs(List<string> files, List<PluginContext> plugi
187187
{
188188
// Create a new load context for this plugin to resolve its dependencies
189189
var loadContext = new PluginLoadContext(file);
190-
var assemblyName = new AssemblyName(Path.GetFileNameWithoutExtension(file));
191-
var assembly = loadContext.LoadFromAssemblyName(assemblyName);
190+
var assembly = loadContext.LoadFromAssemblyPath(file);
192191

193192
var pluginTypes = assembly.GetTypes()
194193
.Where(t => typeof(IBlakePlugin).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);

tests/Blake.IntegrationTests/TestPluginWithDependencies/BlakePlugin.TestPluginWithDependencies.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
</ItemGroup>
1616

1717
<ItemGroup>
18-
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
18+
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.6" />
1919
</ItemGroup>
2020

2121
</Project>

tests/Blake.IntegrationTests/TestPluginWithDependencies/TestPluginWithDependencies.cs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Blake.BuildTools;
22
using Microsoft.Extensions.Logging;
3-
using Newtonsoft.Json;
3+
using SixLabors.ImageSharp;
4+
using SixLabors.ImageSharp.PixelFormats;
45

56
namespace BlakePlugin.TestPluginWithDependencies;
67

@@ -10,15 +11,27 @@ public Task BeforeBakeAsync(BlakeContext context, ILogger? logger = null)
1011
{
1112
logger?.LogInformation("TestPluginWithDependencies: BeforeBakeAsync called");
1213

13-
// Use Newtonsoft.Json to test dependency loading
14-
var testObject = new { Message = "Plugin with dependencies loaded successfully", PageCount = context.MarkdownPages.Count };
15-
var serialized = JsonConvert.SerializeObject(testObject);
14+
// Use SixLabors.ImageSharp to test dependency loading
15+
using var image = new Image<Rgba32>(100, 100);
16+
image.ProcessPixelRows(accessor =>
17+
{
18+
for (int y = 0; y < accessor.Height; y++)
19+
{
20+
var row = accessor.GetRowSpan(y);
21+
for (int x = 0; x < row.Length; x++)
22+
{
23+
row[x] = Color.Blue;
24+
}
25+
}
26+
});
1627

17-
logger?.LogInformation("TestPluginWithDependencies: Serialized data: {SerializedData}", serialized);
28+
var testMessage = $"Plugin with dependencies loaded successfully. Created {image.Width}x{image.Height} image. PageCount: {context.MarkdownPages.Count}";
29+
30+
logger?.LogInformation("TestPluginWithDependencies: {TestMessage}", testMessage);
1831

1932
// Create a marker file to prove the plugin ran with dependencies
2033
var testFilePath = Path.Combine(context.ProjectPath, ".plugin-with-deps-before-bake.txt");
21-
File.WriteAllText(testFilePath, serialized);
34+
File.WriteAllText(testFilePath, testMessage);
2235

2336
return Task.CompletedTask;
2437
}
@@ -27,12 +40,12 @@ public Task AfterBakeAsync(BlakeContext context, ILogger? logger = null)
2740
{
2841
logger?.LogInformation("TestPluginWithDependencies: AfterBakeAsync called with {PageCount} generated pages", context.GeneratedPages.Count);
2942

30-
// Use Newtonsoft.Json again to ensure dependency is still available
31-
var testObject = new { Message = "Plugin dependencies working in AfterBakeAsync", GeneratedPageCount = context.GeneratedPages.Count };
32-
var serialized = JsonConvert.SerializeObject(testObject);
43+
// Use SixLabors.ImageSharp again to ensure dependency is still available
44+
using var image = new Image<Rgba32>(50, 50);
45+
var testMessage = $"Plugin dependencies working in AfterBakeAsync. Created {image.Width}x{image.Height} image. GeneratedPageCount: {context.GeneratedPages.Count}";
3346

3447
var testFilePath = Path.Combine(context.ProjectPath, ".plugin-with-deps-after-bake.txt");
35-
File.WriteAllText(testFilePath, serialized);
48+
File.WriteAllText(testFilePath, testMessage);
3649

3750
return Task.CompletedTask;
3851
}

0 commit comments

Comments
 (0)