-
Notifications
You must be signed in to change notification settings - Fork 152
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
using System.Reflection; | ||
using System.Runtime.Loader; | ||
|
||
namespace Libplanet.Node.Actions; | ||
|
||
public class PluginLoadContext(string pluginPath) : AssemblyLoadContext | ||
{ | ||
private readonly AssemblyDependencyResolver _resolver = new(pluginPath); | ||
|
||
protected override Assembly? Load(AssemblyName assemblyName) | ||
{ | ||
var assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName); | ||
if (assemblyPath is not null) | ||
{ | ||
return LoadFromAssemblyPath(assemblyPath); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
protected override IntPtr LoadUnmanagedDll(string unmanagedDllName) | ||
{ | ||
var libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName); | ||
if (libraryPath is not null) | ||
{ | ||
return LoadUnmanagedDllFromPath(libraryPath); | ||
} | ||
|
||
return IntPtr.Zero; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
using System.Reflection; | ||
using Libplanet.Action; | ||
using Libplanet.Action.Loader; | ||
|
||
namespace Libplanet.Node.Actions; | ||
|
||
public static class PluginLoader | ||
{ | ||
public static IActionLoader LoadActionLoader(string relativePath, string typeName) | ||
{ | ||
Assembly assembly = LoadPlugin(relativePath); | ||
IEnumerable<IActionLoader> loaders = Create<IActionLoader>(assembly); | ||
foreach (IActionLoader loader in loaders) | ||
{ | ||
if (loader.GetType().FullName == typeName) | ||
{ | ||
return loader; | ||
} | ||
} | ||
|
||
throw new ApplicationException( | ||
$"Can't find {typeName} in {assembly} from {assembly.Location}. " + | ||
$"Available types: {string | ||
.Join(",", loaders.Select(x => x.GetType().FullName))}"); | ||
} | ||
|
||
public static IPolicyActionsRegistry LoadPolicyActionRegistry( | ||
string relativePath, | ||
string typeName) | ||
{ | ||
Assembly assembly = LoadPlugin(relativePath); | ||
IEnumerable<IPolicyActionsRegistry> policies = Create<IPolicyActionsRegistry>(assembly); | ||
foreach (IPolicyActionsRegistry policy in policies) | ||
{ | ||
if (policy.GetType().FullName == typeName) | ||
{ | ||
return policy; | ||
} | ||
} | ||
|
||
throw new ApplicationException( | ||
$"Can't find {typeName} in {assembly} from {assembly.Location}. " + | ||
$"Available types: {string | ||
.Join(",", policies.Select(x => x.GetType().FullName))}"); | ||
} | ||
|
||
private static IEnumerable<T> Create<T>(Assembly assembly) | ||
where T : class | ||
{ | ||
int count = 0; | ||
|
||
foreach (Type type in assembly.GetTypes()) | ||
Check warning on line 52 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs GitHub Actions / check-build
|
||
{ | ||
if (typeof(T).IsAssignableFrom(type)) | ||
{ | ||
if (Activator.CreateInstance(type) is T result) | ||
Check warning on line 56 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs GitHub Actions / check-build
|
||
{ | ||
count++; | ||
yield return result; | ||
} | ||
} | ||
} | ||
|
||
if (count == 0) | ||
{ | ||
string availableTypes = string.Join(",", assembly.GetTypes().Select(t => t.FullName)); | ||
throw new ApplicationException( | ||
$"Can't find any type which implements ICommand in {assembly} from {assembly.Location}.\n" + | ||
Check warning on line 68 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs GitHub Actions / check-build
|
||
$"Available types: {availableTypes}"); | ||
} | ||
} | ||
|
||
private static Assembly LoadPlugin(string relativePath) | ||
{ | ||
// Navigate up to the solution root | ||
// string root = Path.GetFullPath(Path.Combine( | ||
// Path.GetDirectoryName( | ||
// Path.GetDirectoryName( | ||
// Path.GetDirectoryName( | ||
// Path.GetDirectoryName( | ||
// Path.GetDirectoryName(typeof(Program).Assembly.Location))))))); | ||
Check warning on line 81 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs GitHub Actions / check-build
|
||
|
||
// string pluginLocation = Path.GetFullPath(Path.Combine(root, relativePath.Replace('\\', Path.DirectorySeparatorChar))); | ||
Check warning on line 83 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs GitHub Actions / check-build
|
||
string pluginLocation = relativePath; | ||
Console.WriteLine($"Loading commands from: {pluginLocation}"); | ||
PluginLoadContext loadContext = new PluginLoadContext(pluginLocation); | ||
return loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(pluginLocation))); | ||
Check warning on line 87 in sdk/node/Libplanet.Node/Actions/PluginLoader.cs GitHub Actions / check-build
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
using Libplanet.Action; | ||
using Libplanet.Action.Loader; | ||
using Libplanet.Node.Actions; | ||
|
||
namespace Libplanet.Node.Options; | ||
|
||
[Options(Position)] | ||
public sealed class ActionOptions : OptionsBase<ActionOptions> | ||
{ | ||
public const string Position = "Action"; | ||
|
||
public string ActionLoaderPath { get; set; } = string.Empty; | ||
|
||
public string ActionLoaderType { get; set; } = string.Empty; | ||
|
||
internal IActionLoader GetActionLoader() | ||
{ | ||
var actionLoaderPath = ActionLoaderPath; | ||
var actionLoaderType = ActionLoaderType; | ||
return PluginLoader.LoadActionLoader(actionLoaderPath, actionLoaderType); | ||
} | ||
|
||
internal IPolicyActionsRegistry GetPolicyActionsRegistry() | ||
{ | ||
// PluginLoader.LoadPolicyActionRegistry(pluginPath, blockPolicyType); | ||
Check warning on line 25 in sdk/node/Libplanet.Node/Options/ActionOptions.cs GitHub Actions / check-build
Check warning on line 25 in sdk/node/Libplanet.Node/Options/ActionOptions.cs GitHub Actions / check-build
Check warning on line 25 in sdk/node/Libplanet.Node/Options/ActionOptions.cs GitHub Actions / docs
Check warning on line 25 in sdk/node/Libplanet.Node/Options/ActionOptions.cs GitHub Actions / docs
|
||
return new PolicyActionsRegistry(); | ||
} | ||
} |