我正在尝试为正在开发的这款游戏进行扩展设置(不做详细介绍),但是一个扩展所需要做的只是将1个.dll文件添加到我添加的Expansions
文件夹中。
我已经弄清楚了如何访问添加到此文件夹中的这些.dll,如下所示:
Assembly ExpAssembly = Assembly.LoadFrom("Expansions/Intrique.dll");
Type myType = ExpAssembly.GetTypes()[0];
这是我要加载的类的示例:
public class Expansion: MyGame.Expansion {
public Expansion() {
//Stuff
}
public string SomeMethod()
{
return "Test";
}
}
调用以下代码即可运行SomeMethod()
MethodInfo Method = myType.GetMethod("SomeMethod");
object myInstance = Activator.CreateInstance(myType);
MessageBox.Show(Method.Invoke(myInstance, null).ToString());
但是我想做的是能够编写
Expansion expObj;
并通过从未引用的.dll中调用new Expansion()
进行分配,但不能在库本身中进行赋值。 最佳答案
(出于此答案的目的,我将假设您的Expansion
子类具有Intrique.Expansion
的完全限定名称。即,名称空间与DLL的名称相同)。
因为您的主程序未引用Intrique.dll,所以主程序中的代码无法直接使用该DLL中的类型。也就是说,在主程序的书面代码中Intrique.Expansion
不是可用的类型,尽管它可以在运行时使用。
从字面上看您的代码示例,鉴于您现在拥有的代码,唯一可行的方法是使用dynamic
:
dynamic myInstance = Activator.CreateInstance(myType);
myInstance.SomeMethod();
这是因为
SomeMethod()
仅在Intrique.Expansion
中声明。在已知该方法的主程序中,不能静态使用任何其他类型。如果该方法是
Intrique.Expansion
实现并由主程序引用的某个接口的成员的实现,或者是override
的某些virtual
成员的MyGame.Expansion
(如果您的主程序引用,则假定为该方法) (实际上没有声明),则可以将实例分别转换为接口类型或MyGame.Expansion
并以这种方式调用方法:ISomeInterface myInstance = (ISomeInterface)Activator.CreateInstance(myType);
myInstance.SomeMethod();
要么:
MyGame.Expansion myInstance = (MyGame.Expansion)Activator.CreateInstance(myType);
myInstance.SomeMethod();
最后,假设您正在尝试实现某种可扩展性体系结构,则可以考虑使用Managed Extensibility Framework,它专门用于处理此类事情的许多混乱部分。