Доброе время суток Коллеги!
возникла некоторирая сложность при работе и не приходит в голову как разрезолвить данную проблему
работа с плагинами
есть интерфейс :
1 сборка
public interface IPlugin
{
bool Start();
event EventHandler<LogEventArgs> OnLog;
}
public class LogEventArgs : EventArgs
{
public string Message { get; set; }
public Exception Error { get; set; }
}
2 сборка сам плагин
public class Test: MarshalByRefObject,IPlugin
{
public bool Start()
{
if(OnLog!=null)
OnLog(this,new LogEventArgs(){Message = "Started"});
return true;
}
public event EventHandler<LogEventArgs> OnLog;
}
3 сборка
использование плагина
class Program
{
static void Main(string[] args)
{
var pl = new PluginController();
Console.WriteLine("before load...");
foreach (var each in AppDomain.CurrentDomain.GetAssemblies().Where(x => typeof(IPlugin).IsAssignableFrom(x.GetTypes().FirstOrDefault())))
{
Console.WriteLine(each.FullName);
}
pl.LoadAllPlugin();
Console.WriteLine("after load...");
foreach (var each in AppDomain.CurrentDomain.GetAssemblies().Where(x => typeof(IPlugin).IsAssignableFrom(x.GetTypes().FirstOrDefault())))
{
Console.WriteLine(each.FullName);
}
pl.UnloadAllPlugin();
Console.WriteLine("after unload...");
foreach (var each in AppDomain.CurrentDomain.GetAssemblies().Where(x => typeof(IPlugin).IsAssignableFrom(x.GetTypes().FirstOrDefault()) ))
{
Console.WriteLine(each.FullName);
}
Console.ReadKey();
}
}
public class PluginController
{
private List<PluginObject> plList;
public PluginController()
{
plList = new List<PluginObject>();
}
public void LoadAllPlugin()
{
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += CurrentDomain_ReflectionOnlyAssemblyResolve;
var pluginsFolder = WebConfigurationManager.AppSettings["PluginDirectory"];
var domainInfo = new AppDomainSetup
{
ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
PrivateBinPath = pluginsFolder
};
var domain = AppDomain.CreateDomain("PluginLoader", null, domainInfo);
foreach (var plugin in Directory.GetFiles(pluginsFolder, "B*.dll", SearchOption.TopDirectoryOnly))
{
var newAssembly = Assembly.ReflectionOnlyLoadFrom(plugin);
var types = newAssembly.GetTypes();
var tx = types.FirstOrDefault(t => typeof(IPlugin).IsAssignableFrom(t));
if (tx == null) return;
var exe = domain.CreateInstanceFromAndUnwrap(tx.Assembly.Location,tx.FullName) as IPlugin;
if (exe != null)
{
exe.OnLog += exe_OnLog;
exe.Start();
plList.Add(new PluginObject(){Domain = domain,plugin = exe});
}
}
}
Assembly CurrentDomain_ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
{
return Assembly.ReflectionOnlyLoad(args.Name);
}
public void UnloadAllPlugin()
{
plList.ForEach(x=>AppDomain.Unload(x.Domain));
}
static void exe_OnLog(object sender, LogEventArgs e)
{
Console.WriteLine(e.Message);
}
}
В итоге вижу :
before load...
Started
after load...
IPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
after unload...
IPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
проблема в том что плагин как мы видим не выгрузился.
в чем и заключается вопрос,как правильнее быть?
p\s но если попытаюсь после анлоада обратиться к нему будет исключение что он выгружен,но тогда почему мы видим что это не так на консоли