天天看點

DotNetCorePlugins- 動态加載和解除安裝 .NET 程式插件

作者:opendotnet
DotNetCorePlugins- 動态加載和解除安裝 .NET 程式插件
DotNetCorePlugins- 動态加載和解除安裝 .NET 程式插件
DotNetCorePlugins- 動态加載和解除安裝 .NET 程式插件

你好,這裡是 Dotnet 工具箱,定期分享 Dotnet 有趣,實用的工具群組件,希望對您有用!

DotNetCorePlugins

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>();

// 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

Dotnet 工具箱

DotNetCorePlugins- 動态加載和解除安裝 .NET 程式插件

分享

DotNetCorePlugins- 動态加載和解除安裝 .NET 程式插件

點收藏

DotNetCorePlugins- 動态加載和解除安裝 .NET 程式插件

繼續閱讀