.net - MEF 最佳实践是什么?

标签 .net silverlight mef

在代码中使用 MEF 的最佳实践有哪些?启动可扩展应用程序时是否有需要考虑的陷阱?你有没有遇到任何你应该早点知道的事情?

最佳答案

我正在 MEF 上构建一个成熟的可扩展应用程序(并使用带有 MVVM 模式的 WPF)。我将自己构建的基本应用程序框架开源为 SoapBox Core 。我还在代码项目中发布了一个基于 SoapBox Core 的演示:Building an Extensible Application with MEF, WPF, and MVVM .

我不确定使用 MVVM 是否适用于您,但如果适用,那么通过使用 MEF 查看 MVVM 的实现,您可能会学到很多东西。特别是它导入 View 的方式。

就最佳实践而言...我创建了一个嵌套的扩展层次结构(因此基本模块称为 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";
        }
    }
}

因此,如果您希望扩展程序向文件菜单添加某些内容,您可以导出使用合约名称 SoapBox.Core.ExtensionPoints.Workbench.MainMenu.FileMenu 实现 IMenuItem 的内容

每个扩展都有一个“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";
            }
        }
    }
}

正如您所看到的,FileMenu 已经包含一个 Exit 扩展(已预先编程为关闭应用程序)。如果您想向"file"菜单添加扩展名,您可能希望它出现在“退出”菜单项之前。 IMenuItem继承自IExtension,它有两个属性:

  • 插入RelativeToID
  • 之前或之后

因此,您的扩展将为 InsertRelativeToID 返回 SoapBox.Core.Extensions.Workbench.MainMenu.FileMenu.Exit,并为 BeforeOrAfter 属性(枚举)返回 Before。当工作台导入所有文件菜单扩展时,它会根据这些 ID 对所有内容进行排序。这样,后面的扩展就会相对于现有扩展插入自己。

关于.net - MEF 最佳实践是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2738052/

相关文章:

.net - 最佳 JIT 优化

C# - LINQ 帮助

c# - Log4Net 比 TraceListener 有什么优势?

c# - 使用 .ashx 文件的 Web 表单的 URL 路由

.net - 为什么需要 Web 服务才能从 Silverlight 访问数据库?

visual-studio-2008 - Silverlight 开发 [Visual Studio 2008 与 Expression Blend]

wpf - 使用 WPF PRISM 4 正常关闭应用程序

dependency-injection - 为什么 MEF 有 [ImportMany] 而不仅仅是 [Import]

.net - 如何通过 SqlDataReader 获取结果集中字符串字段的排序规则?

wpf - 使 silverlight UserControl 填充内容控件中的可用空间