Sor*_*oot 23 .net silverlight mef
在代码中使用MEF的最佳做法是什么?在启动可扩展应用程序时是否有任何陷阱需要考虑?你有没有遇到过你早先应该知道的事情?
我正在MEF上构建一个完全成熟的可扩展应用程序(并使用带有MVVM模式的WPF).我采用了我构建的基本应用程序框架,并将其作为SoapBox Core开源.我还在Code Project上发布了一个基于SoapBox Core的演示:使用MEF,WPF和MVVM构建可扩展应用程序.
我不确定使用MVVM是否适用于您,但如果确实如此,那么通过查看使用MEF的MVVM实现,您可以学到很多东西.特别是它导入视图的方式.
至于最佳实践......我创建了一个嵌套的扩展层次结构(因此基本模块称为Host,它所做的只是组成应用程序并导入一些基本扩展).然后,这些扩展会暴露其他扩展点,并且在运行它时构建自身的应用程序类型(组合和扩展之间的交叉).
为了保持一切顺利,我将扩展层次结构放入一组静态类中.例如,以下是核心框架提供的所有扩展点:
namespace SoapBox.Core.ExtensionPoints
{
public static class Host
{
public const string Styles = "ExtensionPoints.Host.Styles";
public const string Views = "ExtensionPoints.Host.Views";
public const string StartupCommands = "ExtensionPoints.Host.StartupCommands";
public const string ShutdownCommands = "ExtensionPoints.Host.ShutdownCommands";
}
public static class Workbench
{
public const string ToolBars = "ExtensionPoints.Workbench.ToolBars";
public const string StatusBar = "ExtensionPoints.Workbench.StatusBar";
public const string Pads = "ExtensionPoints.Workbench.Pads";
public const string Documents = "ExtensionPoints.Workbench.Documents";
public static class MainMenu
{
public const string Self = "ExtensionPoints.Workbench.MainMenu";
public const string FileMenu = "ExtensionPoints.Workbench.MainMenu.FileMenu";
public const string EditMenu = "ExtensionPoints.Workbench.MainMenu.EditMenu";
public const string ViewMenu = "ExtensionPoints.Workbench.MainMenu.ViewMenu";
public const string ToolsMenu = "ExtensionPoints.Workbench.MainMenu.ToolsMenu";
public const string WindowMenu = "ExtensionPoints.Workbench.MainMenu.WindowMenu";
public const string HelpMenu = "ExtensionPoints.Workbench.MainMenu.HelpMenu";
}
}
public static class Options
{
public static class OptionsDialog
{
public const string OptionsItems = "ExtensionPoints.Options.OptionsDialog.OptionsItems";
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,如果您希望扩展程序向文件菜单添加内容,则可以导出实现IMenuItem的内容,其中包含合同名称SoapBox.Core.ExtensionPoints.Workbench.MainMenu.FileMenu
每个扩展名都有一个"ID",它只是一个字符串标识符.这些现有ID在另一个层次结构中定义:
namespace SoapBox.Core.Extensions
{
public static class Workbench
{
public static class MainMenu
{
public const string File = "File";
public const string Edit = "Edit";
public const string View = "View";
public const string Tools = "Tools";
public const string Window = "Window";
public const string Help = "Help";
public static class FileMenu
{
public const string Exit = "Exit";
}
public static class ViewMenu
{
public const string ToolBars = "ToolBars";
}
public static class ToolsMenu
{
public const string Options = "Options";
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,FileMenu已经包含一个Exit扩展(预编程为关闭应用程序).如果要在"文件"菜单中添加扩展名,可能需要在"退出"菜单项之前显示该扩展名.IMenuItem继承自IExtension,它有两个属性:
因此,您的扩展将为InsertRelativeToID返回SoapBox.Core.Extensions.Workbench.MainMenu.FileMenu.Exit,并为BeforeOrAfter属性(枚举)返回Before.当工作台导入所有文件菜单扩展时,它会根据这些ID对所有内容进行排序.通过这种方式,后面的扩展相对于现有扩展插入自身.
最佳做法是使用Shared(单例)模型.这使我们考虑到设计因素,建议您将可导出部件设计为无状态和线程安全,这样它们就不会受到同一实例上多次调用(可能在不同线程上)的影响.
如果单例模型不适合您,建议使用构建器模式(将导出的部分与实际实例化分开).您应该记住,使用非共享模型是非常昂贵的,因为它使用反射进行实际实例化(通过使用构建器模式,您可以获得相同的结果,减少痛苦).
另请查看http://blogs.microsoft.co.il/blogs/bnaya/archive/2010/01/09/mef-for-beginner-toc.aspx 和cource你知道你可以在这里找到信息:http: //mef.codeplex.com
归档时间: |
|
查看次数: |
3486 次 |
最近记录: |