我正在尝试为正在开发的这款游戏进行扩展设置(不做详细介绍),但是一个扩展所需要做的只是将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,它专门用于处理此类事情的许多混乱部分。

10-08 14:49