• 【.NET 深呼吸】在 .net core app 中使用 Composition


    .NET 中的 Composition ,即 MEF。MEF 说得简单一点,就是它可以在运行阶段动态地发现类型,用于组件扩展方面特别合适。

    .NET Core App 的默认框架并不提供 MEF 有关的 API,但,别忘了 Nuget,那上面有相关的库,而且是官方发布的,不出意外的话,是能用的,而且老周也亲自测过,严重证实是可用的。

    哦,是了,顺便提一下,如果你弄的是 ASP.NET Core 项目,对于组件扩展,你可以不必考虑用 Composition,因为 ASP.NET Core 有强大的依赖注入功能,所以,通过注入,也能做到动态发现组件的效果,而且集成性更好。

    所以,所以嘛,咱们今天说的 Composition 主要是针对 .net core app,默认模板提供的是控制台应用程序,或者类库。当然了,也可能是其他类型的项目,而且开源项目将来也会多起来。

    好了,上面说的都是闲话,咱们开始讲正话。

    首先,你要先建一个 core 的项目,嗯,就选控制台应用吧。

    建好项目之后,打开项目的 Nuget 管理器,搜索:

    System.ComponentModel.Composition

    注意,别搜错了,因为 System.Composition 是挺多的,能搜出一打来,但是,你要细看,System.ComponentModel.Composition 支持 Core。请注视下面这张高清无码截图。

    现在你明白为啥要选这个了,至于说 System.Composition 是否支持在 .net core app 中使用,这个就不知道了,没试,你有空的话可以试试,但上面没有注明支持 core。

    然后安装 System.ComponentModel.Composition 包,安装到项目后,就能用了。来,赶紧试试。

    引入以下这两个命名空间:

    using System.ComponentModel.Composition;
    using System.ComponentModel.Composition.Hosting;

    定义一个接口,作为扩展组件的共同协定。

        public interface IMovie
        {
            void Play();
        }

    它表示某电影院正在上映的电影。

    下面两家影院(组件)近期比较热门。

        public class NewMovie : IMovie
        {
            public void Play()
            {
                Console.WriteLine("此处正在放映《我不是酒神》");
            }
        }
    
        public class NanMovie : IMovie
        {
            public void Play()
            {
                Console.WriteLine("此处正在放映《三烤白骨精》");
            }
        }

    其实这样定义的组件,在运行时还是不能被发现的,我们得让它们导出。方法是……自己看下面代码。

        [Export(typeof(IMovie))]
        public class NewMovie : IMovie
        {
            public void Play()
            {
                Console.WriteLine("此处正在放映《我不是酒神》");
            }
        }
    
        [Export(typeof(IMovie))]
        public class NanMovie : IMovie
        {
            public void Play()
            {
                Console.WriteLine("此处正在放映《三烤白骨精》");
            }
        }

    导出约束有这么几种:

    * 约束类型,这一般是组件的约定接口,就是组件实现的共同接口,比如上面的 IMovie。

    * 约束名,这个嘛,自己赐给它一个名字即可。

    * 混合,就是约束名 + 约束类型。这种方法最为准确,在导入时可以准确找到组件。

    如果 ExportAttribute 应用的目标是组件类,而不是接口类型,这时你至少得手动指定一个约束类型,设置为 IMovie,不然,它默认就是目标类的名字,这样一来,这两个组件就无法保有共同的约束,导入时不容易找出来。

    我为了演示方便,我这些组件的定义与使用都是在同一个程序集中,所以,组件查找范围在当前程序集中。

                // 获取当前程序集
                Assembly assCurr = Assembly.GetExecutingAssembly();
                // 确定组件搜索范围
                AssemblyCatalog catalog = new AssemblyCatalog(assCurr);

    用上面准备好的 Catalog 去初始化 CompositionContainer ,通过容器去获取发现的组件实例。

                using(CompositionContainer container = new CompositionContainer(catalog))
                {
                    // 获取已发现的组件
                    var components = container.GetExportedValues<IMovie>();
                }

    GetExportedValues 方法能直接得到所有发现的组件的实例,如果不想马上用到组件实例,可以获取 Lazy 包装的对象,延时初始化,方法是调用 GetExports 或者 GetExport 方法。

    得到所有组件实例后,可以尝试调用一下。

                using(CompositionContainer container = new CompositionContainer(catalog))
                {
                    // 获取已发现的组件
                    var components = container.GetExportedValues<IMovie>();
                    // 分别调用一下
                    foreach(IMovie m in components)
                    {
                        m.Play();
                    }
                }

    程序运行后,就会输出以下内容。

    看,两个组件都被成功调用了。

    ========================================================================

     最近脑细胞不够用,所以博客写得少了,老周在此表示歉意。等过一段时间,脑细胞复活了,老周有空就多写些简单实用的博文。复杂而不实用的东西老周不太会写,唉,没法了,毕竟老周的水平也比较菜,没见过大世面,没做过大项目,没调过大 bug。最大的项目也就是 1213 个实体类,200 多个存储过程,900 多个表,120 个视图。这种规模,估计是老周这一生做过的最大的项目了。

  • 相关阅读:
    使用哈工大LTP进行文本命名实体识别并保存到txt
    gpu命令cuda命令
    python路径拼接os.path.join()函数的用法
    pytorch利用多个GPU并行计算多gpu
    pytorch 多GPU训练总结(DataParallel的使用)
    解决 win10 pycurl安装出错 Command "python setup.py egg_info" failed with error code 10 编译安装包 安装万金油
    解决:"UnicodeEncodeError: 'ascii' codec can't encode character u'xa0' in position"错误
    windows下多版本python安装与pip安装和pip使用 吐血总结
    Python 能做什么?
    Oracle中的索引详解
  • 原文地址:https://www.cnblogs.com/tcjiaan/p/9306664.html
Copyright © 2020-2023  润新知