2016-12-29 100 views
-1

我建立了一个插件系统,在那里我可以动态加载类到我的应用程序(IModule是一个接口,所以我知道该插件将正确的行为):如何从插件获取类实例?

var dll = Assembly.LoadFile("path/to/a/dll"); 
foreach (Type t in dll.GetExportedTypes()) { 
     if (typeof(IModule).IsAssignableFrom(t)) { 
      IModule mod = (IModule)Activator.CreateInstance(t); 
     } 
} 

所以,从我的“主”的应用,我可以在我的插件中获得并实例化类。现在我想要的是能够从插件中获得“主”应用程序的类。

我试过使用Type.GetType("NameOfClass"),但是返回null

+0

这似乎不应该是一个问题。你卡在哪里? – adv12

+0

仅基于类的名称获取类实例。 –

+0

为什么在这个方向上使用反射?为什么不从你的插件项目引用应用程序并直接引用这些类? – adv12

回答

0

如果你需要做到这一点,而不会改变主模块,事实证明这是必然的。所以下面的建议是kludge,但我认为在这种情况下kludge可能是最好的。

静态方法Assembly.GetCallingAssembly()将返回调用当前方法的程序集,因此您可以做的一件事是找到一个地方,主模块直接调用插件模块的某些方法M。手指交叉,也许有某种初始化方法会在早期得到调用。

M中,调用Assembly.GetCallingAssembly()并将结果填充到某个静态字段中,稍后您可以使用该字段创建主模块中定义的类的实例。

+0

谢谢。我知道这是一个混乱,它是丑陋的,但我真的只是想知道是否有可能。如果这是唯一的方法,并且事实证明这是一个问题,那么我可能会考虑将其固定为“正确”的方式。 –

0

我想你误解了插件式的概念。您应该实现API库,其目的是存储公共插件接口。这些接口将在插件中使用,并通过一些IoC框架实例化您的类。例如,您可以使用Ninject:

public class MyPlugin : IModule 
{ 
    public MyPlugin(MainApp.API.IMainAppInterface instance) 
    { 
     //do something with it. 
    } 
} 

public class MyPluginModule: NinjectModule 
{ 
    protected override void Load(IKernel kernel) 
    { 
     kernel.Bind<MyPlugin>().To<IModule>(); 
    } 
} 

而在您的主应用程序中,您只需从某个文件夹加载这些模块。

+0

我这样做,但我忘了把一些类放在API中。现在的问题是,是否需要更新API,或者是否有办法在不触摸API dll或主应用程序的情况下执行此操作。 –

+0

如果您想访问应用程序的内部功能,您应该更新API。你甚至不需要更新公共的API库,只需添加你自己的,并在你的插件中使用它。如果你想破解这一点 - 你可能会产生很多反映错误的代码,没有人知道它是如何工作的... – eocron

+0

你能否详细说明“反射窃听代码”? –