I have a plugin system where I use MarshalByRefObject
to create isolated domains per plugin, so users can reload their new versions, as they see fit without having to turn off the main application.
Now I have the need to allow a plugin to view which plugins are currently running and perhaps start/stop a specific plugin.
I know how to issue commands from the wrapper, in the below code for example:
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);
}
}
}
So then I could, for example:
var domain = AppDomain.CreateDomain(Name, null, AppSetup);
var assemblyPath = Assembly.GetExecutingAssembly().Location;
var loader = (RemoteLoader)Domain.CreateInstanceFromAndUnwrap(assemblyPath, typeof(RemoteLoader).FullName);
loader.Start();
Of course the above is just a resumed sample...
Then on my wrapper I have methods like:
bool Start(string name);
bool Stop(string name);
Which basically is a wrapper to issue the Start/Stop of a specific plugin from the list and a list to keep track of running plugins:
List<Plugin> Plugins
Plugin is just a simple class that holds Domain
, RemoteLoader
information, etc.
What I don't understand is, how to achieve the below, from inside a plugin. Be able to:
- View the list of running plugins
- Execute the Start or Stop for a specific plugin
Or if this is even possible with MarshalByRefObject
given the plugins are isolated or I would have to open a different communication route to achieve this?