微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

.net – 什么是MEF最佳做法?

代码中使用MEF的最佳做法是什么?启动可扩展应用程序时是否有任何陷阱?你有没有遇到过你以前知道的东西?

解决方法

我正在建立一个完全成熟的可扩展应用程序在MEF(并使用WPF与MVVM模式)。我将基础应用程序框架作为 SoapBox Core开发。我还在Code Project: Building an Extensible Application with MEF,WPF,and MVVM上发布了一个基于SoapBox Core的演示。

我不知道如果使用MVVM适用于您,但如果使用MVVM,则可以通过查看使用MEF的MVVM的实现来学习很多。特别是它导入Views的方式。

就最佳实践而言…我创建了一个嵌套的扩展层次结构(因此基本模块称为主机,所有这些都是组合应用程序并导入一些基本扩展)。那么这些扩展展开其他扩展点,并在运行它时构建自己的应用程序种类(构图和扩展之间的交叉)。

为了保持一切正常,我将扩展层次结构放在一组静态类中。例如,这里是核心框架提供的所有扩展点:

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";
        }
    }
}

所以如果你想让你的扩展添加文件菜单,你将导出一些实现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";
            }
        }
    }
}

您可以看到FileMenu已经包含一个退出扩展(预先编程为关闭应用程序)。如果你想添加一个扩展到文件菜单,你可能希望它出现在退出菜单项之前。 IMenuItem继承自IExtension,它具有两个属性

> InsertRelativetoID
> BeforeOrAfter

所以你的扩展名将返回用于InsertRelativetoID的SoapBox.Core.Extensions.Workbench.MainMenu.FileMenu.Exit,并且将为BeforeOrAfter属性(枚举)返回Before。当工作台导入所有文件菜单扩展名时,它会根据这些ID排序所有内容。以这种方式,后面的扩展插入自己相对于现有的扩展。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐