• 可扩展编程MEF学习笔记


    MEF,全称Managed Extensibility Framework(托管可扩展框架)

    对MEF有这样一段说明:

      Managed Extensibility Framework 或 MEF 是一个用于创建可扩展的轻型应用程序的库。 应用程序开发人员可利用该库发现并使用扩展,而无需进行配置。 扩展开发人员还可以利用该库轻松地封装代码,避免生成脆弱的硬依赖项。 通过 MEF,不仅可以在应用程序内重用扩展,还可以在应用程序之间重用扩展。

    主要原理是C#的依赖注入原则

    代码层级关系

    新建Bootstrapper类继承至BootstrapperBase:

    public class Bootstrapper:BootstrapperBase
        {
            private CompositionContainer m_container;
            public Bootstrapper()
            {
                Initialize();
            }
            protected override void OnStartup(object sender, StartupEventArgs e)
            {
                DisplayRootViewFor<PopupWindowViewModel>();
            }
    
            protected override void Configure()
            {
                m_container = new CompositionContainer(new AggregateCatalog(AssemblySource.Instance.Select(x=>new AssemblyCatalog(x))));
                var batch = new CompositionBatch();
                batch.AddExportedValue<IWindowManager>(new WindowManager());//新建一个窗口管理器添加到IOC中
                batch.AddExportedValue<IEventAggregator>(new EventAggregator());//弱事件添加
                batch.AddExportedValue(m_container);
                m_container.Compose(batch);
            }
            /// <summary>
            /// IOC容器获取实例的方法
            /// </summary>
            /// <param name="service"></param>
            /// <param name="key"></param>
            /// <returns></returns>
            protected override object GetInstance(Type service, string key)
            {
                string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(service) : key;
                var exports = m_container.GetExportedValues<object>(contract);
                var exportList = exports.ToList();//避免直接用exports时 调用2次IEnumerable操作
                if (exportList.Any())
                {
                    return exportList.First();
                }
                throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract));
            }
    
            /// <summary>
            /// IOC容器获取实例的方法
            /// </summary>
            /// <param name="service"></param>
            /// <returns></returns>
            protected override IEnumerable<object> GetAllInstances(Type service)
            {
                return m_container.GetExportedValues<object>(AttributedModelServices.GetContractName(service));
            }
    
            /// <summary>
            /// IOC容器注入实例的方法
            /// </summary>
            /// <param name="instance"></param>
            protected override void BuildUp(object instance)
            {
                m_container.SatisfyImportsOnce(instance);
            }
    
            /// <summary>
            /// 设置加载到AssemblySource中的程序集列表
            /// </summary>
            /// <returns></returns>
            protected override IEnumerable<Assembly> SelectAssemblies()
            {
                List<Assembly> list = base.SelectAssemblies().ToList();
                list.AddRange(new List<Assembly> { Assembly.Load("MyDll") });
                return list;
            }
    
            protected override void OnUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
            {
                e.Handled = true;
            }
        }

    VM继承至Screen

    [Export(typeof(PopupWindowViewModel))]
        public class PopupWindowViewModel:Screen
        {
            public IWindowManager _WindowManager { get; set; }
            [ImportingConstructor]//必须加入这个,这是因为用MEF在创建ViewModel实例时,有[ImportingConstructor]标记的构造函数的参数会自动使用容器内相应的export对象
            public PopupWindowViewModel(IWindowManager windowManager)
            {
                this._WindowManager = windowManager;
            }
            protected override void OnInitialize()
            {
                _WindowManager.ShowDialog(new MainViewModel());
            }
            public void PopupForm()
            {
                _WindowManager.ShowWindow(new EditUserViewModel(_WindowManager));
            }
        }

    实现效果

    典型的MEF组合过程

      (1)创建组件目录(如AssemblyCatalog)

      (2)创建组合容器CompositionContainer,组件容器通过组件目录搜索组件的定义

      (3)创建一个组件

      (4)从组件容器获取其它组件功能的定义,然后执行匹配组合

    参考链接:https://kb.cnblogs.com/page/97675/

  • 相关阅读:
    APP 打包成功的四种方法 转自
    设置启动页
    大数据之医疗行业数据分析
    实验三(FCFS ,SJF,HRRN)
    实验四 用信号量解决进程互斥与同步问题
    实验二 (3)最短作业优先调度
    实验二 (2)优先数调度
    实验二 (1)先来先服务进程调度
    实验一
    Hdoj 1253
  • 原文地址:https://www.cnblogs.com/dujian123/p/14742222.html
Copyright © 2020-2023  润新知