我有一个插件系统,其中我使用
现在我需要允许一个插件查看当前正在运行的插件,并可能启动/停止特定的插件。
我知道如何从包装器中发出命令,在下面的代码中:
当然,上述内容只是一个简要示例...
然后在我的封装器中,我有像这样的方法:
基本上它是一个包装器,用于从列表中发出特定插件的启动/停止指令和一个用于跟踪正在运行的插件的列表:
MarshalByRefObject
创建每个插件的隔离域,因此用户可以重新加载他们认为合适的新版本,而无需关闭主应用程序。现在我需要允许一个插件查看当前正在运行的插件,并可能启动/停止特定的插件。
我知道如何从包装器中发出命令,在下面的代码中:
using System;
using System.Linq;
using System.Reflection;
using System.Security.Permissions;
namespace Wrapper
{
public class RemoteLoader : MarshalByRefObject
{
private Assembly _pluginAassembly;
private object _instance;
private string _name;
public RemoteLoader(string assemblyName)
{
_name = assemblyName;
if (_pluginAassembly == null)
{
_pluginAassembly = AppDomain.CurrentDomain.Load(assemblyName);
}
// Required to identify the types when obfuscated
Type[] types;
try
{
types = _pluginAassembly.GetTypes();
}
catch (ReflectionTypeLoadException e)
{
types = e.Types.Where(t => t != null).ToArray();
}
var type = types.FirstOrDefault(type => type.GetInterface("IPlugin") != null);
if (type != null && _instance == null)
{
_instance = Activator.CreateInstance(type, null, null);
}
}
public void Start()
{
if (_instance == null)
{
return;
}
((IPlugin)_instance).OnStart();
}
public void Stop()
{
if (_instance == null)
{
return;
}
((IPlugin)_instance).OnStop(close);
}
}
}
那么我可以,例如:
var domain = AppDomain.CreateDomain(Name, null, AppSetup);
var assemblyPath = Assembly.GetExecutingAssembly().Location;
var loader = (RemoteLoader)Domain.CreateInstanceFromAndUnwrap(assemblyPath, typeof(RemoteLoader).FullName);
loader.Start();
当然,上述内容只是一个简要示例...
然后在我的封装器中,我有像这样的方法:
bool Start(string name);
bool Stop(string name);
基本上它是一个包装器,用于从列表中发出特定插件的启动/停止指令和一个用于跟踪正在运行的插件的列表:
List<Plugin> Plugins
插件只是一个简单的类,包含Domain
、RemoteLoader
信息等。
我不明白的是,如何从插件内部实现以下操作:
- 查看正在运行的插件列表
- 执行特定插件的启动或停止操作
如果插件被隔离了,那么使用MarshalByRefObject
是否可能实现此功能?还是说我需要打开另一条通信路线来实现这个操作?