为了让您的组件位于外壳中而两者之间没有任何通信,您需要将特定模块的所有逻辑(保存/加载等)放入该模块中。
但是,很可能在不耦合实现的情况下让 shell 与插件通信,尽管您可能需要考虑在两者之间建立一些通用机制。
很可能你会想要一个用于你的 shell 项目的可扩展性框架库,它有一个你可以编程的通用 API,以便更好地集成你的插件
MEF 允许您非常轻松地进行插件发现/加载等。在设计插件风格框架时,接口是你的朋友。让你的插件实现一个特定的接口意味着你的 shell 可以与插件对话,同时不知道插件的实际作用
一个简单的示例可能是工具栏的命令集合(每个插件都可以使用工具栏注册命令,该工具栏将根据可用的命令动态创建按钮):
在您的可扩展性库中(shell 和插件都引用此库):
public interface IProvideCommands
{
public IList<IToolBarCommand> AvailableCommands { get; }
}
您可能还需要一个标记界面来让 shell 应用程序知道插件程序集中的哪些 ViewModel 类型是它应该加载到您的动态区域中的那些(您已经在某种程度上做到了,您是如何实现的?)
public interface IPluginShell { }
在您的插件主 VM 中:
public class SomePluginViewModel : IPluginShell, IProvideCommands
{
public IList<IToolBarCommand> AvailableCommands { get; private set; } // Populate this etc
}
在你的外壳中:
public class ApplicationShell
{
public ApplicationShell()
{
// Load plugins
....
// Discover commands
var commandProvider = SomePlugin as IProvideCommands;
if(commandProvider != null)
{
DoStuffWith(commandProvider.Commands);
}
}
}
然后,命令受插件的支配——它们可以指示 shell 可以使用哪些命令,而不是 shell 必须知道有关 VM 本身的任何信息。
让我知道这是否有帮助