插件架构和共享接口问题

时间:2009-12-09 10:28:54

标签: c# plugins interface

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

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

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

问题:如何处理?

2 个答案:

答案 0 :(得分:2)

我担心编译器不会帮助你。插件A可以在构建B之前,期间或之后随时更改,因此您的插件体系结构需要应对可能的接口丢失 - 返回接口的空值或抛出异常。

至于获取正确类型的项目,可以使用泛型来实现:

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

所以强制转换是在GetAction方法而不是调用者(有点)中完成的:

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

编辑:

如果做&lt;&gt;在通话中太多了,试试:

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!
}

答案 1 :(得分:0)

两个选项:

  1. 检查您的对象(使用'as')而不是仅仅转换它(并更新程序逻辑以处理对象未实现接口的情况)
  2. 向共享DLL添加一个接口,允许插件通知其他人其功能,并提供强类型方法以获取各种接口的实现。然后,所有插件都应实现此接口,并使用其方法获取对其他插件中的功能的引用。