在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";
}
}
}
[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";
}
}
}
ProxyObject obj = (ProxyObject)ad.CreateInstanceFromAndUnwrap(@"D:/messageDll/Classes.dll", "com.ms.AbcTest2");
// 这一步就提示错误System.Runtime.Serialization.SerializationException: 未解析成员
然后用 Activator.CreateInstance 不行么
主要需要实现动态的卸载程序集,目的使得该服务升级不需要重启服务。但是没有Assembly.unload这样的方法,查阅了网上的一些解决方案,都是将其放到一个appdomin中的。然后条用appdomin.unload方法。
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";
}
}
}
Object obj = ad.CreateInstanceFromAndUnwrap(@"D:/messageDll/Classes.dll", "com.ms.AbcTest2");
public class AbcTest2 : MarshalByRefObject //, ILogicalThreadAffinative
...此时实例倒是创建成功了,不过它的类型为MarshalByRefObject 无法调用到它的方法,报空引用异常~~
-load 加载默认目录
-loaddir Directory 加载目录
-loadfile DllPath 加载插件文件
-runall 执行所有插件
-run PluginName 执行插件
-unload DllName 卸载插件
-unloadall 卸载所有插件
-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 ...
反射呀。
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";
}
}
}
另外,ls提到面向接口也是有道理的。你想强类型的使用加载之后的对象。
那么就需要定义一个接口,WebService需要引用接口所在的dll。
而动态加载实例所在的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页