2009-12-09 74 views
2

我正在使用C#插件体系结构。插件是DLL的暴露一堆演示者,这是实现IPresenter接口的对象。 IPresenter接口可在所有插件共享的DLL中使用。演示者还可以实现IAction接口定义的其他方法,如ILoadAction,ISaveAction等。这些接口也由同一个DLL共享,因此所有插件都可以具有实现此类接口的演示者。插件体系结构和共享接口问题

案例:我在插件A中有演示者X,它实现了IPresenter接口和ILoadAction接口。在插件B中,我要求插件架构给我一个演示者X.这给了我一个对象IP地址 IPresenter。要调用该演示者的LoadAction方法,我必须将演示者转换为ILoadAction。

问题:如果我从插件A中的演示者X中删除ILoadAction,插件B中的代码仍将编译,即使演示者不再实现ILoadAction。在这种情况下,我想要被编译器警告。其实,我想避免不得不一直施展到某个IAction ...

问题:如何处理?

回答

0

两个选项:

  1. 检查对象(使用“为”),而不是仅仅铸造它(并更新你的程序逻辑来处理的情况下对象没有实现的接口)
  2. 添加一个到你的共享DLL的接口,允许一个插件通知其他的功能,并提供强类型的方法来获得各种接口的实现。所有插件都应该实现这个接口,并使用它的方法来获得对其他插件中的功能的引用。
+0

这些选项实际上不会产生编译时错误,如果你删除该接口为您的问题描述,但这决不是因为整点编译时错误你的插件方法似乎是插件没有明确地耦合到其他功能,但可以有'额外的方法'。 如果你想编译时间检查:只是强制所有插件实施ILoadAction ... – 2009-12-09 10:44:25

+0

-1这听起来不像一个可扩展的体系结构。想象一下,在开发了数百个实现之后,您现在需要添加另一个“功能”。这意味着在界面中添加另一种方法,从而破坏数百个实现。 – 2009-12-09 10:46:35

2

恐怕编译器不会帮你在这里。插件A可以在构建B之前,之中或之后随时更改,因此插件体系结构需要应对可能的接口丢失 - 要么为接口返回空值,要么抛出异常。

至于正确类型的获取项目,这可以来达到的使用泛型:

T IPresenter.GetAction <T> where T : class, IAction() 
{ 
    return (T) GetAction (typeof T) 
} 

所以中投在的getAction方法完成,而不是调用者(排序):

var action = PluginA.GetAction <ILoadAction>(); 

编辑:

如果调用做<>实在是太多了,试试:

bool GetAction<T> (out T a) where T : class, IAction 
{ 
    // stuff 
    return interface_found; // or throw an exception? 
} 

然后,你可以这样做:

ILoadAction action; 
if (!PluginA.GetAction (out action)) 
{ 
    // failed to get interface! 
}