C# 使用MEF扩展.NET应用程序中的菜单和上下文菜单

C# 使用MEF扩展.NET应用程序中的菜单和上下文菜单,c#,menu,mef,extensibility,C#,Menu,Mef,Extensibility,我正试图提出一个菜单和上下文菜单体系结构,类似于VisualStudio2010提供的,这样我就可以用扩展提供的附加子项扩展当前菜单。我正在使用MEF()。 例如,Resharper扩展在任何可能的位置(上下文菜单或菜单项的顶部、中部或底部)添加菜单项和上下文菜单项 如何才能提供这样的功能?我是否必须为shell的每个菜单项编制索引,并让扩展名引用索引来定位其子项? 我希望我的问题足够清楚。如果不是的话,我非常乐意补充一些说明。我不确定是否有一个最好的方法来做到这一点。但这里有一些想法需要考虑:

我正试图提出一个菜单和上下文菜单体系结构,类似于VisualStudio2010提供的,这样我就可以用扩展提供的附加子项扩展当前菜单。我正在使用MEF()。 例如,Resharper扩展在任何可能的位置(上下文菜单或菜单项的顶部、中部或底部)添加菜单项和上下文菜单项 如何才能提供这样的功能?我是否必须为shell的每个菜单项编制索引,并让扩展名引用索引来定位其子项?
我希望我的问题足够清楚。如果不是的话,我非常乐意补充一些说明。

我不确定是否有一个最好的方法来做到这一点。但这里有一些想法需要考虑:

一个相当简单的解决方案是使用单个契约(即IMenuIten)并使用元数据来控制命令出现在哪个菜单中以及在哪个位置。一种方法是建立一个“索引”,尽管它可能应该是一个双精度的,用于对菜单中的项目进行排序,这样每个项目就不需要知道它在菜单中的绝对位置。另一种方法是在菜单项上添加元数据,该元数据提供了应在当前项之前和之后的其他项的列表。然后,您可以对菜单项进行拓扑排序,以获得显示它们的顺序

根据菜单行为的复杂性/动态性,您可能会发现无法使用导出元数据很好地表达菜单行为。在这种情况下,您可以将功能移动到契约本身,即在IMenuItem契约上添加属性或方法。这样,您就可以运行代码来计算所需的值

另一个解决方案是根本不直接导出菜单项。相反,您可以使用由组件导入的菜单服务。该服务将有一个Register方法,可以将菜单项添加到菜单中。在我看来,这使得添加菜单项变得相当麻烦,所以我不会推荐它,除非你有理由需要它。如果可用菜单项应根据应用程序的当前上下文进行更改,这可能是合适的。请注意,如果您这样做,仅拥有一个导入菜单服务的类不会导致创建和组合该类。类需要导出系统中其他地方导入的内容