这是今天课堂上的一个小例子程序
1. 接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Interfaces
{
public interface IPlugin
{
void Run();
}
}
2. 插件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PluginLib
{
[Serializable]
public class Plugin:Interfaces.IPlugin
{
public void Run() {
Console.WriteLine("插件在运行");
}
}
}
3. 主程序
AppDomain plugindomain = AppDomain.CreateDomain("PluginDomain");
#region 使用接口的方式来动态执行方法
Interfaces.IPlugin plugin = (Interfaces.IPlugin)plugindomain.CreateInstanceFromAndUnwrap("PluginLib.dll", "PluginLib.Plugin");
plugin.Run();
Console.WriteLine("在插件程序域中加载的程序集");
foreach (var item in plugindomain.GetAssemblies())
{
Console.WriteLine(item.FullName);
}
#endregion
结果如下
注意:这种方式加载的插件,里面的类型必须声明可序列化([Serializable] ),否则就会出现下面的错误
但是,如果插件真的没有声明可序列化,是不是就没有办法呢?也不是这么说
4. 在主程序中添加一个TypeLoader
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;
namespace _08_AppDomain_ServiceSample
{
[Serializable]
public class TypeLoader
{
public Assembly LoadAssembly(string path) {
return Assembly.LoadFile(Path.Combine(Environment.CurrentDirectory, path));
}
}
}
5. 修改代码,利用TypeLoader作为中间人,去动态加载那些插件程序集
#region 使用加载代理的方式
TypeLoader loader = (TypeLoader)plugindomain.CreateInstanceFromAndUnwrap("08_AppDomain_ServiceSample.exe", typeof(TypeLoader).FullName);
Interfaces.IPlugin plugin = (Interfaces.IPlugin)loader.LoadAssembly("PluginLib.dll").CreateInstance("PluginLib.Plugin");
plugin.Run();
Console.WriteLine("在插件程序域中加载的程序集");
foreach (var item in plugindomain.GetAssemblies())
{
Console.WriteLine(item.FullName);
}
AppDomain.Unload(plugindomain);
#endregion