我正在制作一个基于组件的系统(每个对象将所有功能委托给可以在运行时添加的各种组件),并希望能够在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
- 您可能希望添加额外的条件,例如公共类型等