DotNetCorePlugins 是一个 .NET 的开源插件项目,它提供了能够动态加载程序集的 API,然后把它们作为 .NET 主程序的扩展程序执行。这个库主要用到了
AssemblyLoadContext 技术,
System.Runtime.Loader.AssemblyLoadContext,又名 ALC,提供了一些用于定义动态程序集加载行为的基本 API。这是 .NET Core 中我最喜欢但鲜为人知的 API 之一。
如何使用?
安装 McMaster.NETCore.Plugins NuGet 包。
dotnet add package McMaster.NETCore.Plugins
主要使用的 API 是 PluginLoader.CreateFromAssemblyFile, 它允许从文件中读取并加载程序集。
PluginLoader.CreateFromAssemblyFile(
assemblyFile: "./plugins/MyPlugin/MyPlugin1.dll",
sharedTypes: new [] { typeof(IPlugin), typeof(IServiceCollection), typeof(ILogger) },
isUnloadable: true)
assemblyFile = 插件 .dll 的文件路径
sharedTypes = 加载程序的统一的类型列表
isUnloadable = 允许这个插件在将来的某个时候从内存中卸载。
定义接口
这是一个示例,我们定义了一个接口,里面包含了 GetName, 如下
public interface IPlugin
{
string GetName();
}
对于插件,我们直接使用这个接口并进行实现,如下
internal class MyPlugin1 : IPlugin
{
public string GetName() => "My plugin v1";
}
对于主程序,我们可以使用 PluginLoader API 来加载插件,程序需要使用查找磁盘中的插件程序集。一种方式是基于约定的,比如
plugins/
$PluginName1/
$PluginName1.dll
(additional plugin files)
$PluginName2/
$PluginName2.dll
每个插件都发布到一个单独的目录中,这样可以避免插件之间的争用和重复的依赖问题。
以通过运行下面的命令,输出插件到文件夹中。
dotnet publish MyPlugin1.csproj --output plugins/MyPlugin1/
接下来,我们可以通过反射获取所有的插件,并进行加载, 代码如下
using McMaster.NETCore.Plugins;
var loaders = new List<PluginLoader>();
// 堆代码 duidaima.com
// create plugin loaders
var pluginsDir = Path.Combine(AppContext.BaseDirectory, "plugins");
foreach (var dir in Directory.GetDirectories(pluginsDir))
{
var dirName = Path.GetFileName(dir);
var pluginDll = Path.Combine(dir, dirName + ".dll");
if (File.Exists(pluginDll))
{
var loader = PluginLoader.CreateFromAssemblyFile(
pluginDll,
sharedTypes: new [] { typeof(IPlugin) });
loaders.Add(loader);
}
}
// Create an instance of plugin types
foreach (var loader in loaders)
{
foreach (var pluginType in loader
.LoadDefaultAssembly()
.GetTypes()
.Where(t => typeof(IPlugin).IsAssignableFrom(t) && !t.IsAbstract))
{
IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType);
Console.WriteLine($"Created plugin instance '{plugin.GetName()}'.");
}
}
支持 MVC 和 Razor
另外插件还支持加载 MVC 的 Controller 和 Razor Pages。通过安装下面的 Nuget 包。
dotnet add package McMaster.NETCore.Plugins.Mvc
加载程序集的方法如下:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
var pluginFile = Path.Combine(AppContext.BaseDirectory, "plugins/MyRazorPlugin/MyRazorPlugin.dll");
services
.AddMvc()
.AddPluginFromAssemblyFile(pluginFile);
}
}
更多插件的使用方法,作者提供了一些示例项目,可以进行参考。
https://github.com/natemcmaster/DotNetCorePlugins