Creating instances from strings over different namespaces and different assemblies
I am making a component based system (each object delegates all functionality to a variety of components which can be added at runtime) and want to be able to define my objects in XML files for ease. I know how to use Activator.CreateInstance
to create my objects from strings, but I require full classnames and assembly names.
The issue comes from the fact that these components may be either pre-built in my library (say assembly FirstAssembly.dll
and namespace Foo.Bar
) or defined specifically for my game (say assembly SecondAssembly.dll
and namespace 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>
The last solution would be easy, if rather annoying - I ne开发者_JAVA百科ed assembly names, or at least some way of saying 'component from library' or 'component from game'.
The second solution is probably easier - I just need (some way) of checking - probably just try/catch
- if the class is in FirstAssembly; if not, try SecondAssembly.
The first solution is what I really want to do, but I do not think it possible. The amount of namespaces would make it difficult.
tl;dr Is there a way I can make this system work so my XML files look as close to the first solution as possible? If not, is the second solution viable?
It sounds like you want something like:
Type targetType = (from assembly in candidateAssemblies
from type in assembly.GetTypes()
where type.Name == nameFromXml
select type).FirstOrDefault();
Note that:
- If there are multiple matches, this will just return the first one.
- If there are no matches, this will return
null
- You may wish to add extra conditions, such as public types etc
精彩评论