在 C# 中从 Assembly.LoadFrom() 返回对象
Returning into object from Assembly.LoadFrom() in C#
我正在尝试为我正在开发的这个游戏做一个扩展设置,(不打算详细介绍),但是所有一个扩展都需要将 1 个 .dll 文件添加到 Expansions
我添加的文件夹。
我已经弄清楚如何访问添加到此文件夹中的这些 .dll,如下所示:
Assembly ExpAssembly = Assembly.LoadFrom("Expansions/Intrique.dll");
Type myType = ExpAssembly.GetTypes()[0];
这是我正在尝试加载的 class 的示例:
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
实现并且您的主程序引用的某个接口成员的实现,或者是 MyGame.Expansion
的某些 virtual
成员的 override
(这大概是你的主程序引用,如果没有实际声明),那么你可以将实例分别转换为接口类型或 MyGame.Expansion
并以这种方式调用方法:
ISomeInterface myInstance = (ISomeInterface)Activator.CreateInstance(myType);
myInstance.SomeMethod();
或:
MyGame.Expansion myInstance = (MyGame.Expansion)Activator.CreateInstance(myType);
myInstance.SomeMethod();
最后,鉴于您正在尝试实现某种可扩展性架构,您可以考虑使用 Managed Extensibility Framework,它专门设计用于处理这类事情的许多混乱部分。
我正在尝试为我正在开发的这个游戏做一个扩展设置,(不打算详细介绍),但是所有一个扩展都需要将 1 个 .dll 文件添加到 Expansions
我添加的文件夹。
我已经弄清楚如何访问添加到此文件夹中的这些 .dll,如下所示:
Assembly ExpAssembly = Assembly.LoadFrom("Expansions/Intrique.dll");
Type myType = ExpAssembly.GetTypes()[0];
这是我正在尝试加载的 class 的示例:
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
实现并且您的主程序引用的某个接口成员的实现,或者是 MyGame.Expansion
的某些 virtual
成员的 override
(这大概是你的主程序引用,如果没有实际声明),那么你可以将实例分别转换为接口类型或 MyGame.Expansion
并以这种方式调用方法:
ISomeInterface myInstance = (ISomeInterface)Activator.CreateInstance(myType);
myInstance.SomeMethod();
或:
MyGame.Expansion myInstance = (MyGame.Expansion)Activator.CreateInstance(myType);
myInstance.SomeMethod();
最后,鉴于您正在尝试实现某种可扩展性架构,您可以考虑使用 Managed Extensibility Framework,它专门设计用于处理这类事情的许多混乱部分。