- 定义一个类库,定义接口
csharp
namespace Plugin
{
public interface IPlugin
{
void EllisTest();
}
}
- 定义另外一个类库,引用上面的类库,实现接口
csharp
using Plugin;
namespace UserCustom
{
public class Custom : IPlugin
{
public void EllisTest()
{
Console.WriteLine("哈哈,今天这个天气挺好的");
}
}
}
- 定义API,使用assemble加载dll
csharp
[HttpGet(Name = "test")]
public IActionResult DirectLoad()
{
Assembly assembly = Assembly.LoadFrom("C:\\Users\\84977\\Desktop\\UserCustom.dll");
var pluginType = assembly.GetTypes().FirstOrDefault(t => typeof(IPlugin).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);
if (pluginType != null)
{
IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType);
plugin.EllisTest();
}
return Ok();
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
string pluginPath = "C:\\Users\\84977\\Desktop\\UserCustom.dll";
var pluginLoader = new PluginLoader();
pluginLoader.LoadAndExecutePlugin(pluginPath);
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
- 使用AssemblyLoadContext 加载dll
csharp
public class CustomAssemblyLoadContext : AssemblyLoadContext
{
public CustomAssemblyLoadContext() : base(isCollectible: true)
{
}
protected override Assembly Load(AssemblyName assemblyName)
{
return null; // 返回 null 以使用默认的加载机制
}
}
public class PluginLoader
{
public void LoadAndExecutePlugin(string pluginPath)
{
var context = new CustomAssemblyLoadContext();
// 加载插件程序集
var assembly = context.LoadFromAssemblyPath(pluginPath);
// 查找实现了 IPlugin 接口的类型
var pluginType = assembly.GetTypes().FirstOrDefault(t => typeof(IPlugin).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);
if (pluginType != null)
{
// 创建插件实例并调用方法
var plugin = (IPlugin)Activator.CreateInstance(pluginType);
plugin.EllisTest();
}
assembly = null;
GC.Collect();
GC.WaitForPendingFinalizers();
context.Unload();
// 在此处,当 using 块结束时,AssemblyLoadContext 会被卸载,从而实现 DLL 的热卸载。
}
}