我一直在努力创建一个类似命令行的模块应用程序。每个模块可以容纳多个命令。例如,“模块A”可以具有诸如“退出”和“回声”的命令。我正在使用以下代码加载和初始化我的模块......
foreach (string Filename in Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Modules"), "*.dll"))
{
Assembly Asm = Assembly.LoadFrom(Filename);
foreach (Type AsmType in Asm.GetTypes())
{
if (AsmType.GetInterface("ICommandModule") != null)
{
object CommandObject = Activator.CreateInstance(AsmType);
ICommandModule CommandModule;
if (CommandObject is ICommandModule)
{
CommandModule = (ICommandModule)CommandObject;
}
else
{
throw new Exception("CommandObject is not a valid ICommandModule.");
}
...
我知道它正在加载的模块(Core.dll)完全符合ICommandModule接口。当我确定if (CommandObject is ICommandModule)
时,它会抛出异常。当我完全删除if语句时,它告诉我它无法将CommandObject
转换为ICommandModule
。
答案 0 :(得分:1)
采取Jakub的建议并进行此更改:
ICommandModule CommandModule = Activator.CreateInstance(AsmType) as ICommandModule;
您可能遇到Activator.CreateInstance(AsmType)返回null的情况。如果是这样,它可能是它找到了接口本身的声明,并且没有可能为该特定的AsmType创建实例。因此,在调试时,请确保您确切知道要尝试实例化的类型。
答案 1 :(得分:1)
您可以使用Reflection来检查对象是否实现了特定的接口。
以下是一个例子:
bool isCommandModule = typeof(ICommandModule).IsAssignableFrom(commandObject);
相关资源:
答案 2 :(得分:1)
您的应用程序可能在两个不同的目录中使用ICommandModule查找程序集。程序集可能完全相同,但由于它们位于不同的目录中,因此类型系统将它们视为不同。
答案 3 :(得分:0)
尝试:
CommandModule = CommandObject as ICommandModule;