C# 动态加载,卸载dll。

吃啥补傻 2011-08-01 10:43:30
在webService中,需要动态的加载和卸载dll,请各路神仙帮忙看下问题所在。


[WebMethod]
public string ko()
{
AppDomain ad = AppDomain.CreateDomain("Classes");
ProxyObject obj = (ProxyObject)ad.CreateInstanceFromAndUnwrap(@"D:/messageDll/Classes.dll", "com.ms.AbcTest2"); // 这一步就提示错误System.Runtime.Serialization.SerializationException: 未解析成员
obj.LoadAssembly();
string strResult=obj.Invoke(@"D:/messageDll/Classes.dll", "HelloWorld").ToString();
AppDomain.Unload(ad);
return strResult;
}


调用的dll如下

namespace com.ms
{
[Serializable]
public class AbcTest2 : ILogicalThreadAffinative
{
public AbcTest2()
{
//
// TODO: Add constructor logic here
//
}

public string HelloWorld()
{
return "Hello World ahhahahahahahah";
}
}
}


...全文
1153 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
ysy30040 2012-07-27
  • 打赏
  • 举报
回复
我也遇到这个问题了,求解答
xiaohong 2012-03-14
  • 打赏
  • 举报
回复
我操,我TMD最近也遇到这个问题了。坐等求解
ayun00 2012-03-12
  • 打赏
  • 举报
回复
同样的问题
_程序员 2011-09-17
  • 打赏
  • 举报
回复
using System.Reflection;

Assembly ass = Assembly.Load("testdll"); //加载dll文件
Type tp = ass.GetType("testdll.MyClass"); //获取类名,必须 命名空间+类名
Object obj = Activator.CreateInstance(tp,"男"); //建立实例
PropertyInfo meth = tp.GetProperty("Six"); //获取方法
Console.WriteLine(meth.GetValue(obj,null)); //Invoke调用方法


//.dll文件要放在bin\debug文件夹下
<C#入门经典4>812页
josephzen 2011-09-17
  • 打赏
  • 举报
回复
appDomain.CreateInstanceFromAndUnwrap

这个方法貌似对dll文件有要求,要是Assembly有unload就方便了
机器人 2011-08-01
  • 打赏
  • 举报
回复
var appDomain = AppDomain.CreateDomain("MyDomain");
var obj = appDomain.CreateInstanceFromAndUnwrap(@"MyTestLib.dll", "MyTestLib.Class1");
var result = obj.GetType().GetMethod("Foo").Invoke(obj, null);
Console.WriteLine(result);

//MyTestLib.dll
namespace MyTestLib
{
public class Class1
{
public string Foo()
{
return "MyTestLib.Class1.Foo";
}
}
}


  • 打赏
  • 举报
回复
重启服务有几毛钱损失呢?论证过吗?
机器人 2011-08-01
  • 打赏
  • 举报
回复
public class AbcTest2 : ILogicalThreadAffinative

加个继承

public class AbcTest2 : ILogicalThreadAffinative, MarshalByRefObject
吃啥补傻 2011-08-01
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 fangxinggood 的回复:]

另外个问题,为啥要用Domain,为了隔离吗?

直接用 Assembly.LoadFile / LoadFrom
然后用 Activator.CreateInstance 不行么
[/Quote]

主要需要实现动态的卸载程序集,目的使得该服务升级不需要重启服务。但是没有Assembly.unload这样的方法,查阅了网上的一些解决方案,都是将其放到一个appdomin中的。然后条用appdomin.unload方法。
机器人 2011-08-01
  • 打赏
  • 举报
回复
另外个问题,为啥要用Domain,为了隔离吗?

直接用 Assembly.LoadFile / LoadFrom
然后用 Activator.CreateInstance 不行么
吃啥补傻 2011-08-01
  • 打赏
  • 举报
回复

ProxyObject obj = (ProxyObject)ad.CreateInstanceFromAndUnwrap(@"D:/messageDll/Classes.dll", "com.ms.AbcTest2");
// 这一步就提示错误System.Runtime.Serialization.SerializationException: 未解析成员
吃啥补傻 2011-08-01
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 fangxinggood 的回复:]

ProxyObject obj = (ProxyObject)ad.CreateInstanceFromAndUnwrap

这种的要求对象是可序列化的,在类上加 [Serializable] 特性
[/Quote]

已经加了哦,看第二段代码
机器人 2011-08-01
  • 打赏
  • 举报
回复
ProxyObject obj = (ProxyObject)ad.CreateInstanceFromAndUnwrap

这种的要求对象是可序列化的,在类上加 [Serializable] 特性
吃啥补傻 2011-08-01
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 fangxinggood 的回复:]

AppDomain appDomain = AppDomain.CreateDomain("MyDomain");
object obj = appDomain.CreateInstanceFromAndUnwrap(@"MyTestLib.dll", "MyTestLib.Class1");
object result = obj.GetType().GetMethod("Foo").Invoke(obj, null);
Console.WriteLine(result);

//MyTestLib.dll
namespace MyTestLib
{
public class Class1
{
public string Foo()
{
return "MyTestLib.Class1.Foo";
}
}
}
[/Quote]


新建了个控制台程序,和你一样的代码,然后将编译好的dll放到debug文件夹下,运行,提示未标记可序列化错误,确定没有[Serializable]吗?
机器人 2011-08-01
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 yijianzuifen 的回复:]

引用 8 楼 fangxinggood 的回复:

C# code
var appDomain = AppDomain.CreateDomain("MyDomain");
var obj = appDomain.CreateInstanceFromAndUnwrap(@"MyTestLib.dll", "MyTestLib.Class1");
var result = obj.GetT……
[/Quote]

另外,ls提到面向接口也是有道理的。你想强类型的使用加载之后的对象。
那么就需要定义一个接口,WebService需要引用接口所在的dll。
而动态加载实例所在的dll。然后上面可以强制转换成该接口并调用。

机器人 2011-08-01
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 yijianzuifen 的回复:]

引用 8 楼 fangxinggood 的回复:

C# code
var appDomain = AppDomain.CreateDomain("MyDomain");
var obj = appDomain.CreateInstanceFromAndUnwrap(@"MyTestLib.dll", "MyTestLib.Class1");
var result = obj.GetT……
[/Quote]

反射呀。
AppDomain appDomain = AppDomain.CreateDomain("MyDomain");
object obj = appDomain.CreateInstanceFromAndUnwrap(@"MyTestLib.dll", "MyTestLib.Class1");
object result = obj.GetType().GetMethod("Foo").Invoke(obj, null);
Console.WriteLine(result);

//MyTestLib.dll
namespace MyTestLib
{
public class Class1
{
public string Foo()
{
return "MyTestLib.Class1.Foo";
}
}
}

吃啥补傻 2011-08-01
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 xuyiazl 的回复:]

http://download.csdn.net/source/3485843

自己去下吧~
[/Quote]

已下,非常感谢,不过是vs2010的,看不出效果,只好先看看代码了。
xuyiazl 2011-08-01
  • 打赏
  • 举报
回复
help
-load 加载默认目录
-loaddir Directory 加载目录
-loadfile DllPath 加载插件文件
-runall 执行所有插件
-run PluginName 执行插件
-unload DllName 卸载插件
-unloadall 卸载所有插件
-load
load : E:\PluginPlatform\bin\Debug\Plugins\PluginSample.dll
load : E:\PluginPlatform\bin\Debug\Plugins\PluginSample1.dll
-runall
Hello Sample1
Hello Sample2
Hello Sample3
Hello Sample4
-unloadall
unload PluginSample done ...
unload PluginSample1 done ...
lyp464686109 2011-08-01
  • 打赏
  • 举报
回复
u p
xuyiazl 2011-08-01
  • 打赏
  • 举报
回复
help
-load 加载默认目录
-loaddir Directory 加载目录
-loadfile DllPath 加载插件文件
-runall 执行所有插件
-run PluginName 执行插件
-unload DllName 卸载插件
-unloadall 卸载所有插件

加载更多回复(7)

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧