我有在运行时加载的自定义程序集。
此时我有加载dll的代码,可以创建对象andexecute方法的新实例。
如何验证该类是否实现了我在接口中定义的所有函数。
(我正在尝试使用可在运行时切换的不同操作创建插件系统,以提供不同的行为)。
我的代码就像这是主程序:
public Interface IArticleManager{
void SetMenuId(int MenuId);
void SetMenu(string name);
void SetContent(string content);
bool Save();
}
我的类库(断开连接,你可以从解决方案中看到它)
public class XmlArticle{
public void SetMenuId(int MenuId){
//some implementation
}
public void SetMenu(string name){
//some implementation
}
public void SetContent(string content){
//some implementation
}
public bool Save(){
}
}
public class SqlArticle{
public void SetMenuId(int MenuId){
//some implementation
}
public void SetMenu(string name){
//some implementation
}
public void SetContent(string content){
//some implementation
}
public bool Save(){
}
}
答案 0 :(得分:3)
基本上,要改写一下,你想检查一个类是否定义了一个接口的契约,即使它没有明确地实现那个接口?
这非常非常重要,而且非常非常糟糕。相反,我强烈建议您将插件接口重构为合同程序集,并从插件和主应用程序引用程序集。然后,您的插件实际上可以实现合同,并且您可以避免编译器保护,从而搞乱实现。
但是,如果你坚持沿着这条路走下去,那么:
var interfaceType = typeof(IArticleManager);
var targetType = typeof(SqlArticle);
foreach(var member in interfaceType.GetMembers())
{
var targetMember = targetType.GetMember(member.Name);
// compare the arguments, generic constraints, etc here
}
我会留给你做比较,因为它老实说是大量的编码。您需要检查该成员是属性,事件或方法,通用或非通用等。
答案 1 :(得分:1)
检查一个类实现接口中的所有方法是没有用的,除非它实际实现了接口本身 - 事实上它具有相同的方法名称最终只是巧合。
要检查对象实例是否实现了接口:
if (obj is IArticleManager)
将返回true。
但是,如果你想实际使用界面的方法,那就更好(少投射):
IArticleManager manager = obj as IArticleManager;
if (manager != null)
{ do stuff }
答案 2 :(得分:1)
看起来你需要做的就是将接口移动到一个单独的程序集中,该程序集只包含“主程序”和动态加载的DLL都可以访问的接口。
因此,为了创建动态加载的DLL并期望它在您的基础结构中工作,作者首先需要引用接口程序集,然后实现提供的接口。
答案 3 :(得分:0)
IArticleManager
当你不能在任何地方使用它时,目的是什么?
除此之外,如果我们接受你想制作一个非常松散的插件系统,你可以强制要求每个插件程序集只有一个公共类,然后通过反射实例化该类,并通过反射调出它的方法,同时传递适当的参数。
与每个插件或其他外部代码一样,您应该验证输出并保护您的应用程序免受错误(即捕获并记录插件异常)。这也可以处理无效的插件(没有所需签名的插件)