我使用AppDomain动态加载程序集,实现热插拔功能,但是在Console程序中可以正常使用 跨域委托,在Asp.net中绑定事件时提示调用的目标发生异常。
加载程序集代码
using System;namespace AssemblyLoader
{
//代理类
public class Proxy : MarshalByRefObject
{
private System.Reflection.Assembly _assembly; //加载程序集
public void LoadAssembly(string assemblyFile)
{
this._assembly = System.Reflection.Assembly.LoadFrom(assemblyFile);
} //根据类名创建对象
public object GetObject(string FullClassName)
{
object obj = _assembly.CreateInstance(FullClassName, true, new System.Reflection.BindingFlags(), null, null, null, null);
return obj;
} //根据类名和类型创建对象
public T GetInstance<T>(string FullClassName) where T : class
{
return GetObject(FullClassName) as T;
}
}
}
using System;namespace AssemblyLoader
{
//加载程序集
public class Loader
{
private AppDomain _appDomain;
private Proxy _proxy; //初始化代理
public void InitProxy(string applicationName, string domainName, string currentAssemblyFile, string privateBinPath)
{
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationName = applicationName;
setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
setup.PrivateBinPath = privateBinPath;
setup.CachePath = setup.ApplicationBase;
setup.ShadowCopyFiles = "true";
setup.ShadowCopyDirectories = setup.ApplicationBase;
setup.DisallowBindingRedirects = false;
setup.DisallowCodeDownload = true;
setup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
System.Security.Policy.Evidence adevidence = AppDomain.CurrentDomain.Evidence;
this._appDomain = AppDomain.CreateDomain(domainName, adevidence, setup);
var currentAssembly = System.Reflection.Assembly.GetExecutingAssembly();
string assemblyName = currentAssembly.GetName().FullName;
this._proxy = (Proxy)this._appDomain.CreateInstanceFrom(currentAssembly.Location, typeof(Proxy).FullName).Unwrap();
} //加载程序集 调用代理
public void LoadAssembly(string assemblyFile)
{
this._proxy.LoadAssembly(assemblyFile);
} //根据类名创建对象 调用代理
public object GetObject(string FullClassName)
{
object obj = this._proxy.GetObject(FullClassName);
return obj;
} //根据类名和类型创建对象 调用代理
public T GetInstance<T>(string FullClassName) where T : class
{
return this._proxy.GetInstance<T>(FullClassName);
} //卸载程序域
public void Unload()
{
try
{
if (this._appDomain != null)
{
AppDomain.Unload(this._appDomain);
this._appDomain = null;
}
}
catch (Exception)
{
throw;
}
}
}
}
插件基类代码using System;namespace Compents
{
//委托
public class Delegates : MarshalByRefObject
{
public Func<object, object> GetObject;
}
}using System;namespace Compents
{
//接口
public interface IPlugin
{
void Nomal(); object Run(object obj);
}
}
插件代码
using System;
using Compents;namespace TestPlugin
{
public class MyPlugin : Delegates, IPlugin
{
public void Nomal()
{
Console.WriteLine("Nomal");
} public object Run(object obj)
{
object objec = this.GetObject(obj);
return objec;
}
}
}
在Console中运行正常
using System;
using AssemblyLoader;
using Compents;namespace ConsoleApp
{
public class Program
{
static string dir = @"E:\LAB\TestPlugin\TestPlugin\bin\Debug";
static string dll = @"E:\LAB\TestPlugin\TestPlugin\bin\Debug\TestPlugin.dll"; static void Main(string[] args)
{
try
{
Loader service = new Loader();
string fullname = service.GetType().Assembly.FullName;
service.InitProxy("TestApplication", "TestAppdomain", fullname, dir);
service.LoadAssembly(dll);
object obj = service.GetObject("TestPlugin.MyPlugin"); if (obj is IPlugin)
{
IPlugin plugin = obj as IPlugin;
plugin.Nomal();
} if (obj is Delegates)
{
Delegates del = obj as Delegates;
del.GetObject += MyClass.GetString;
} if (obj is IPlugin)
{
IPlugin plugin = obj as IPlugin;
MyObject myobj = new MyObject();
myobj.something = "this is some line!";
object result = plugin.Run(myobj);
MyObject o = result as MyObject;
Console.WriteLine(o.something);
} Console.WriteLine("Run Complate");
Console.Read();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.Read();
}
}
} public class MyClass
{
public static object GetString(object str)
{
return str;
}
} public class MyObject : MarshalByRefObject
{
public string something { get; set; }
}
}
同样的代码在Asp.net中就异常
using System;
using AssemblyLoader;
using Compents;namespace WebApplication1
{
public partial class WebForm2 : System.Web.UI.Page
{
string dir = @"E:\LAB\TestPlugin\TestPlugin\bin\Debug";
string dll = @"E:\LAB\TestPlugin\TestPlugin\bin\Debug\TestPlugin.dll"; protected void Page_Load(object sender, EventArgs e)
{
try
{
Loader service = new Loader();
string fullname = service.GetType().Assembly.FullName;
service.InitProxy("TestApplication", "TestAppdomain", fullname, dir);
service.LoadAssembly(dll);
object obj = service.GetObject("TestPlugin.MyPlugin"); if (obj is IPlugin)
{
IPlugin plugin = obj as IPlugin;
plugin.Nomal();
} if (obj is Delegates)
{
Delegates del = obj as Delegates;
del.GetObject += MyClass.GetString;//这一句抛出异常 调用的目标发生了异常
} if (obj is IPlugin)
{
IPlugin plugin = obj as IPlugin;
MyObject myobj = new MyObject();
myobj.something = "this is some line!";
object result = plugin.Run(myobj);
MyObject o = result as MyObject;
Console.WriteLine(o.something);
} Console.WriteLine("Run Complate");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
} public class MyClass
{
public static object GetString(object str)
{
return str;
}
} public class MyObject : MarshalByRefObject
{
public string something { get; set; }
}
}上述就是全部代码,在Asp.net中提示调用的目标发生了异常。我找了好久也没找到异常的原因,请各位大神帮我看看哪里有问题。
谢谢!
加载程序集代码
using System;namespace AssemblyLoader
{
//代理类
public class Proxy : MarshalByRefObject
{
private System.Reflection.Assembly _assembly; //加载程序集
public void LoadAssembly(string assemblyFile)
{
this._assembly = System.Reflection.Assembly.LoadFrom(assemblyFile);
} //根据类名创建对象
public object GetObject(string FullClassName)
{
object obj = _assembly.CreateInstance(FullClassName, true, new System.Reflection.BindingFlags(), null, null, null, null);
return obj;
} //根据类名和类型创建对象
public T GetInstance<T>(string FullClassName) where T : class
{
return GetObject(FullClassName) as T;
}
}
}
using System;namespace AssemblyLoader
{
//加载程序集
public class Loader
{
private AppDomain _appDomain;
private Proxy _proxy; //初始化代理
public void InitProxy(string applicationName, string domainName, string currentAssemblyFile, string privateBinPath)
{
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationName = applicationName;
setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
setup.PrivateBinPath = privateBinPath;
setup.CachePath = setup.ApplicationBase;
setup.ShadowCopyFiles = "true";
setup.ShadowCopyDirectories = setup.ApplicationBase;
setup.DisallowBindingRedirects = false;
setup.DisallowCodeDownload = true;
setup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
System.Security.Policy.Evidence adevidence = AppDomain.CurrentDomain.Evidence;
this._appDomain = AppDomain.CreateDomain(domainName, adevidence, setup);
var currentAssembly = System.Reflection.Assembly.GetExecutingAssembly();
string assemblyName = currentAssembly.GetName().FullName;
this._proxy = (Proxy)this._appDomain.CreateInstanceFrom(currentAssembly.Location, typeof(Proxy).FullName).Unwrap();
} //加载程序集 调用代理
public void LoadAssembly(string assemblyFile)
{
this._proxy.LoadAssembly(assemblyFile);
} //根据类名创建对象 调用代理
public object GetObject(string FullClassName)
{
object obj = this._proxy.GetObject(FullClassName);
return obj;
} //根据类名和类型创建对象 调用代理
public T GetInstance<T>(string FullClassName) where T : class
{
return this._proxy.GetInstance<T>(FullClassName);
} //卸载程序域
public void Unload()
{
try
{
if (this._appDomain != null)
{
AppDomain.Unload(this._appDomain);
this._appDomain = null;
}
}
catch (Exception)
{
throw;
}
}
}
}
插件基类代码using System;namespace Compents
{
//委托
public class Delegates : MarshalByRefObject
{
public Func<object, object> GetObject;
}
}using System;namespace Compents
{
//接口
public interface IPlugin
{
void Nomal(); object Run(object obj);
}
}
插件代码
using System;
using Compents;namespace TestPlugin
{
public class MyPlugin : Delegates, IPlugin
{
public void Nomal()
{
Console.WriteLine("Nomal");
} public object Run(object obj)
{
object objec = this.GetObject(obj);
return objec;
}
}
}
在Console中运行正常
using System;
using AssemblyLoader;
using Compents;namespace ConsoleApp
{
public class Program
{
static string dir = @"E:\LAB\TestPlugin\TestPlugin\bin\Debug";
static string dll = @"E:\LAB\TestPlugin\TestPlugin\bin\Debug\TestPlugin.dll"; static void Main(string[] args)
{
try
{
Loader service = new Loader();
string fullname = service.GetType().Assembly.FullName;
service.InitProxy("TestApplication", "TestAppdomain", fullname, dir);
service.LoadAssembly(dll);
object obj = service.GetObject("TestPlugin.MyPlugin"); if (obj is IPlugin)
{
IPlugin plugin = obj as IPlugin;
plugin.Nomal();
} if (obj is Delegates)
{
Delegates del = obj as Delegates;
del.GetObject += MyClass.GetString;
} if (obj is IPlugin)
{
IPlugin plugin = obj as IPlugin;
MyObject myobj = new MyObject();
myobj.something = "this is some line!";
object result = plugin.Run(myobj);
MyObject o = result as MyObject;
Console.WriteLine(o.something);
} Console.WriteLine("Run Complate");
Console.Read();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.Read();
}
}
} public class MyClass
{
public static object GetString(object str)
{
return str;
}
} public class MyObject : MarshalByRefObject
{
public string something { get; set; }
}
}
同样的代码在Asp.net中就异常
using System;
using AssemblyLoader;
using Compents;namespace WebApplication1
{
public partial class WebForm2 : System.Web.UI.Page
{
string dir = @"E:\LAB\TestPlugin\TestPlugin\bin\Debug";
string dll = @"E:\LAB\TestPlugin\TestPlugin\bin\Debug\TestPlugin.dll"; protected void Page_Load(object sender, EventArgs e)
{
try
{
Loader service = new Loader();
string fullname = service.GetType().Assembly.FullName;
service.InitProxy("TestApplication", "TestAppdomain", fullname, dir);
service.LoadAssembly(dll);
object obj = service.GetObject("TestPlugin.MyPlugin"); if (obj is IPlugin)
{
IPlugin plugin = obj as IPlugin;
plugin.Nomal();
} if (obj is Delegates)
{
Delegates del = obj as Delegates;
del.GetObject += MyClass.GetString;//这一句抛出异常 调用的目标发生了异常
} if (obj is IPlugin)
{
IPlugin plugin = obj as IPlugin;
MyObject myobj = new MyObject();
myobj.something = "this is some line!";
object result = plugin.Run(myobj);
MyObject o = result as MyObject;
Console.WriteLine(o.something);
} Console.WriteLine("Run Complate");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
} public class MyClass
{
public static object GetString(object str)
{
return str;
}
} public class MyObject : MarshalByRefObject
{
public string something { get; set; }
}
}上述就是全部代码,在Asp.net中提示调用的目标发生了异常。我找了好久也没找到异常的原因,请各位大神帮我看看哪里有问题。
谢谢!
你尝试把未加载的dll,通过代码加载试试。