-
Notifications
You must be signed in to change notification settings - Fork 149
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
using System.Reflection; | ||
using Libplanet.Action; | ||
using Libplanet.Action.Loader; | ||
using Libplanet.Blockchain.Policies; | ||
|
||
namespace Libplanet.Node.API; | ||
|
||
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()) | ||
{ | ||
if (typeof(T).IsAssignableFrom(type)) | ||
{ | ||
T result = Activator.CreateInstance(type) as T; | ||
if (result != null) | ||
{ | ||
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" + | ||
$"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))))))); | ||
|
||
string pluginLocation = Path.GetFullPath(Path.Combine(root, relativePath.Replace('\\', Path.DirectorySeparatorChar))); | ||
Console.WriteLine($"Loading commands from: {pluginLocation}"); | ||
PluginLoadContext loadContext = new PluginLoadContext(pluginLocation); | ||
return loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(pluginLocation))); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
using System.Reflection; | ||
using System.Runtime.Loader; | ||
|
||
namespace Libplanet.Node; | ||
|
||
public class PluginLoadContext : AssemblyLoadContext | ||
{ | ||
private AssemblyDependencyResolver _resolver; | ||
|
||
public PluginLoadContext(string pluginPath) | ||
{ | ||
_resolver = new AssemblyDependencyResolver(pluginPath); | ||
} | ||
|
||
protected override Assembly Load(AssemblyName assemblyName) | ||
{ | ||
string assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName); | ||
if (assemblyPath != null) | ||
{ | ||
return LoadFromAssemblyPath(assemblyPath); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
protected override IntPtr LoadUnmanagedDll(string unmanagedDllName) | ||
{ | ||
string libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName); | ||
if (libraryPath != null) | ||
{ | ||
return LoadUnmanagedDllFromPath(libraryPath); | ||
} | ||
|
||
return IntPtr.Zero; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
using System.Collections.Immutable; | ||
|
||
namespace Libplanet.Action | ||
{ | ||
public interface IPolicyActionsRegistry | ||
{ | ||
/// <summary> | ||
/// An array of <see cref="IAction"/> to execute and be rendered at the beginning | ||
/// for every block, if any.</summary> | ||
ImmutableArray<IAction> BeginBlockActions | ||
{ | ||
get; | ||
} | ||
Check warning on line 13 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (linux-8cores)
Check warning on line 13 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / docs
Check warning on line 13 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (windows-8cores)
|
||
/// <summary> | ||
Check warning on line 14 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (linux-8cores)
Check warning on line 14 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (linux-8cores)
Check warning on line 14 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / docs
Check warning on line 14 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / docs
Check warning on line 14 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (windows-8cores)
Check warning on line 14 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (windows-8cores)
|
||
/// An array of <see cref="IAction"/> to execute and be rendered at the end | ||
/// for every block, if any.</summary> | ||
ImmutableArray<IAction> EndBlockActions | ||
{ | ||
get; | ||
} | ||
Check warning on line 20 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (linux-8cores)
Check warning on line 20 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / docs
Check warning on line 20 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (windows-8cores)
|
||
/// <summary> | ||
Check warning on line 21 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (linux-8cores)
Check warning on line 21 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (linux-8cores)
Check warning on line 21 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / docs
Check warning on line 21 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / docs
Check warning on line 21 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (windows-8cores)
Check warning on line 21 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (windows-8cores)
|
||
/// An array of <see cref="IAction"/> to execute and be rendered at the beginning | ||
/// for every transaction, if any.</summary> | ||
ImmutableArray<IAction> BeginTxActions | ||
{ | ||
get; | ||
} | ||
Check warning on line 27 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (linux-8cores)
Check warning on line 27 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / docs
Check warning on line 27 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (windows-8cores)
|
||
/// <summary> | ||
Check warning on line 28 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (linux-8cores)
Check warning on line 28 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (linux-8cores)
Check warning on line 28 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / docs
Check warning on line 28 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / docs
Check warning on line 28 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (windows-8cores)
Check warning on line 28 in src/Libplanet.Action/IPolicyActionsRegistry.cs GitHub Actions / Run Benchmark.Net benchmarks (windows-8cores)
|
||
/// An array of <see cref="IAction"/> to execute and be rendered at the end | ||
/// for every transaction, if any.</summary> | ||
ImmutableArray<IAction> EndTxActions | ||
{ | ||
get; | ||
} | ||
} | ||
} |