• MEF(Managed Extensibility Framework)有选择性地使用扩展组件


    在"MEF(Managed Extensibility Framework)使用全部扩展组件"中,客户端应用程序调用了所有的扩展组件,而且如果有新的扩展组件加入,必须先关闭程序,再重新启动才可以调用所有组件。

    本篇体验使用MEF的ExportMetadata特性,有选择性地使用某些扩展组件,使用Lazy<>,让客户端程序延迟动态加载组件,即使不关闭应用程序,也能调用所有组件。

     

    2

    ● StudentMEF.Lib, 类库,包含接口IStudent.cs
    ● StudentMEF.One,类库,包含实现IStudent的类One.cs
    ● StudentMEF.Two,类库,包含实现IStudent的类One.cs
    ● StudentMEF.Client,控制台程序

     

    □ 所有扩展满足的约定是

    namespace StudentMEF.Lib
    {
        public interface IStudent
        {
            string GetName();
            int GetScore();
        }
    }

     

    □ StudentMEF.One类库

    → 需引用StudentMEF.Lib组件
    → 需引用System.ComponentModel.Composition组件

     

    using System.ComponentModel.Composition;
    using StudentMEF.Lib;

    namespace StudentMEF.One
    {
        [Export(typeof(IStudent))]
        [ExportMetadata("Type","ONE")]

        public class One : IStudent
        {
            private string _Name;
            private int _Score;

            public One()
            {
                _Name = "jack";
                _Score = 80;
            }
            public string GetName()
            {
                return _Name;
            }

            public int GetScore()
            {
                return _Score;
            }
        }
    }

     

    □ StudentMEF.Two类库

    → 需引用StudentMEF.Lib组件
    → 需引用System.ComponentModel.Composition组件

     

    using System.ComponentModel.Composition;
    using StudentMEF.Lib;

    namespace StudentMEF.Two
    {
        [Export(typeof(IStudent))]
        [ExportMetadata("Type","TWO")]

        public class Two : IStudent
        {
            private string _Name;
            private int _Score;

            public Two()
            {
                _Name = "Bob";
                _Score = 90;
            }

            public string GetName()
            {
                return _Name;
            }

            public int GetScore()
            {
                return _Score;
            }
        }
    }

     

    □ StudentMEF.Client控制台程序

    → 需引用StudentMEF.Lib组件
    → 需引用System.ComponentModel.Composition组件
    → 需在可执行程序所在目录,即生成路径下,创建Extensions文件夹

     

    需要一个帮助类StudentFactory,他的职责包括:

    1、为了动态加载Extensions文件夹的所有扩展组件,可以使用Lazy<>来动态实现延迟加载,即只有当客户端程序使用到Extensions文件夹中组件的时候,再去加载这些扩展组件。
    2、把扩展组件放到Catalog中,在CompositionContainer构建Part等,这些常规操作,也都需要。
    3、提供一个方法,根据元数据ExportMetadata来获取对应的组件。

     

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.ComponentModel.Composition.Hosting;
    using StudentMEF.Lib;

    namespace StudentMEF.Client
    {
        public class StudentFactory
        {
            [ImportMany]
            private Lazy<IStudent, IDictionary<string, object>>[] Students { get; set; }

            public StudentFactory()
            {
                var catalog = new AggregateCatalog();
                catalog.Catalogs.Add(new DirectoryCatalog(@".Extensions"));
                var container = new CompositionContainer(catalog);
                container.ComposeParts(this);
            }

            public List<IStudent> GetStudents(string c)
            {
                List<IStudent> result = new List<IStudent>();
                foreach (var student in Students)
                {
                    if ((string)student.Metadata["Type"] == c)
                    {
                        result.Add(student.Value);
                    }
                }
                return result;
            }     
        }
    }

    Lazy<IStudent, IDictionary<string, object>>中,第二个参数IDictionary<string, object>与ExportMetadata("Type","TWO")对应。

            static void Main(string[] args)
            {
                string c = "";
                while (true)
                {
                    Console.WriteLine("输入学生类型:");
                    c = Console.ReadLine();
                    StudentFactory studentFactory = new StudentFactory();
                    List<IStudent> students = studentFactory.GetStudents(c.ToUpper());
                    if (students.Count == 0)
                    {
                        Console.WriteLine("没有此类型学生~");
                    }
                    else
                    {
                        foreach (IStudent student in students)
                        {
                            Console.WriteLine(string.Format("姓名:{0},分数:{1}",student.GetName(),student.GetScore()));
                        }
                    }
                }
                Console.ReadKey();
            }

     

    当Extensions文件夹中只有StudentMEF.One.dll组件,输入one,找到匹配,输入two找不到匹配;不关闭控制台程序,把StudentMEF.Two.dll也放入 Extensions文件夹,再输入two,找到匹配。      

    1

  • 相关阅读:
    linux command line send email
    js的小随笔
    JavaScript的严格模式
    nodejs学习笔记<六>文件处理
    nodejs学习笔记<五>npm使用
    nodejs学习笔记<四>处理请求参数
    nodejs学习笔记<三>关于路由(url)
    nodejs学习笔记<一>安装及环境搭建
    转:HTTP 301 跳转和302跳转的区别
    前端代码新写法——Zen Coding
  • 原文地址:https://www.cnblogs.com/darrenji/p/3738398.html
Copyright © 2020-2023  润新知