我有一个用C#编写的DLL。在这个DLL中有一个定义的类。 我们假设这个DLL的代码是:
namespace unloadableDLL
{
public class DivisionClass
{
public /*static*/ long Division(long x, long y)
{
// We deliberately do not use a try catch to catch divide by 0 exceptions
return (x / y);
}
}
}
现在,我想在测试程序中动态加载此DLL。我需要看看如果在以下两种情况下除以零会发生什么: 1)直接加载DLL(不使用AppDomain) 2)不直接加载DLL,首先创建AppDomain,然后加载DLL。
我是C#的新手,新的我的意思是我在不到4个小时前开始,但我有C ++背景。
我的问题是,在我的测试程序中,我需要实现一个DivisionClass对象,但这个只在DLL中声明。 =>解决
我的测试程序是
class Program
{
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
static void Main(string[] args)
{
// Load the DLL
Console.WriteLine("Attempting to load unloadableDLL");
Assembly a = Assembly.LoadFrom("./unloadableDLL.dll");
unloadableDLL.DivisionClass divisionObject = (unloadableDLL.DivisionClass)a.CreateInstance("unloadableDLL.DivisionClass");
long number = divisionObject.Division(8, 2);
Console.WriteLine(number);
}
}
我不知道除了编译器一直告诉我静态成员unloadableDLL.DivisionClass.Division(lon,long)无法使用实例引用访问的内容;用typename来限定它。
谢谢大家
答案 0 :(得分:3)
要加载到单独的AppDomain中,从那里执行方法 - 使用反射,如下面的StackOverflow question。它确实涉及通常是一个更高级的C#主题,但代码是相当的样板,对于具有C ++知识的人来说,它不应该存在问题。
对于直接调用,然后按照上面列出的方法进行操作 - 即在项目中引用dll并根据Oded实例化代码(不幸的是,删除了他的答案,以便在下面复制)
DivisionClass.Division(1, 2)
修改强>
如果方法不是静态的
通过反射调用方法
Assembly myAssembly1 = Assembly.LoadFrom("myPath\\Assembly1.dll");
Type myType = myAssembly1.GetType("MyClass");
object myObject = Activator.CreateInstance(myType);
myType.Invoke("myMethodName", BindingFlags.InvokeMethod, null, myObject, null);
在单独的App域中增加了复杂性 - 请参阅link。
此外,我认为你的分类不会按原样运作。要调用应用程序域,您需要对类使用某种序列化或从MarshalByRefObject继承该类 - 请参阅此SO question。鉴于这看起来像是一个概念证明类型/你的类的基础实现,那么MarshalByRefObject将是你最好的选择 - 我认为最简单。这表示跨AppDomains执行可能会很繁琐。
通过代码中的instaniation调用方法
DivisionClass divisor = new DivisionClass()
divisor.Division(1,2)