通过不同命名空间和不同程序集上的字符串创建实例

本文关键字:字符串 创建 实例 命名空间 程序集 | 更新日期: 2023-09-27 17:58:46

我正在制作一个基于组件的系统(每个对象将所有功能委托给可以在运行时添加的各种组件),并希望能够在XML文件中轻松定义我的对象。我知道如何使用Activator.CreateInstance从字符串创建对象,但我需要完整的类名和程序集名。

这个问题来自于这样一个事实,即这些组件可能是在我的库中预先构建的(比如组件FirstAssembly.dll和名称空间Foo.Bar),也可能是专门为我的游戏定义的(比如程序集SecondAssembly.dll和名称空间Second.Blah)。

//In some assembly FirstAssembly.dll
namespace Foo.Bar
{
class SomeClassA
{
}
class SomeClassB
{
}
}
//In some assembly SecondAssembly.dll
namespace Second.Blah
{
class SomeClassC
{
}
class SomeClassD
{
}
}
//In my XML..I would much prefer
<class="SomeClassA"...> </class>
<class="SomeClassD"...> </class>
//Over this, which would just need to check FirstAssembly and SecondAssembly and error handle
<class="Foo.Bar.SomeClassB"...></class>
<class="Second.Blah.SomeClassD"...></class>
//Which I would much prefer over
<class="Foo.Bar.SomeClassB" assembly="FirstAssembly"...></class>
<class="Second.Blah.SomeClassD" assembly="SecondAssembly"...></class>

最后一个解决方案很简单,尽管很烦人——我需要程序集名称,或者至少用某种方式表示"库中组件"或"游戏中组件"。

第二种解决方案可能更容易——我只需要(某种方式)检查——可能只需要try/catch——如果类在FirstAssembly中;如果没有,请尝试SecondAssembly。

第一个解决方案是我真正想做的,但我认为这是不可能的。名称空间的数量会使它变得困难。

tl;dr有没有一种方法可以让这个系统工作,使我的XML文件看起来尽可能接近第一个解决方案?如果没有,第二种解决方案可行吗?

通过不同命名空间和不同程序集上的字符串创建实例

听起来你想要这样的东西:

Type targetType = (from assembly in candidateAssemblies
                   from type in assembly.GetTypes()
                   where type.Name == nameFromXml
                   select type).FirstOrDefault();

注意:

  • 如果有多个匹配项,则只返回第一个匹配项
  • 如果没有匹配,则返回null
  • 您可能希望添加额外的条件,例如公共类型等