.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 个视图。这种规模,估计是老周这一生做过的最大的项目了。

【.NET 深呼吸】在 .net core app 中使用 Composition的更多相关文章

  1. 在 .NET Core 5 中集成 Create React app

    翻译自 Camilo Reyes 2021年2月22日的文章 <Integrate Create React app with .NET Core 5> [1] Camilo Reyes ...

  2. 006.Adding a controller to a ASP.NET Core MVC app with Visual Studio -- 【在asp.net core mvc 中添加一个控制器】

    Adding a controller to a ASP.NET Core MVC app with Visual Studio 在asp.net core mvc 中添加一个控制器 2017-2-2 ...

  3. 008.Adding a model to an ASP.NET Core MVC app --【在 asp.net core mvc 中添加一个model (模型)】

    Adding a model to an ASP.NET Core MVC app在 asp.net core mvc 中添加一个model (模型)2017-3-30 8 分钟阅读时长 本文内容1. ...

  4. 007.Adding a view to an ASP.NET Core MVC app -- 【在asp.net core mvc中添加视图】

    Adding a view to an ASP.NET Core MVC app 在asp.net core mvc中添加视图 2017-3-4 7 分钟阅读时长 本文内容 1.Changing vi ...

  5. 【.NET 深呼吸】.net core 中的轻量级 Composition

    记得前面老周写过在.net core 中使用 Composition 的烂文.上回老周给大伙伴们介绍的是一个“重量级”版本—— System.ComponentModel.Composition.应该 ...

  6. 通过重建Hosting系统理解HTTP请求在ASP.NET Core管道中的处理流程[下]:管道是如何构建起来的?

    在<中篇>中,我们对管道的构成以及它对请求的处理流程进行了详细介绍,接下来我们需要了解的是这样一个管道是如何被构建起来的.总的来说,管道由一个服务器和一个HttpApplication构成 ...

  7. 在 C# App 中嵌入 Chrome 浏览器使用 CefSharp

    介绍 以前曾试过在app中整合一个可靠又快速的web浏览器吗? 在本文中,你会学到如何轻松地将奇妙的CefSharp网页浏览器组件(基于Chromium)集成到你的C# app中. 然后,你可以使用此 ...

  8. .Net Core 项目中的包引用探索(使用VSCode)

    本文组织有点乱,先说结论吧: 1 在 project.json 文件中声明包引用. 而不是像以前那样可以直接引用 dll. 2 使用 dotnet restore 命令后,nuget 会把声明的依赖项 ...

  9. Core管道中的处理流程3

    通过重建Hosting系统理解HTTP请求在ASP.NET Core管道中的处理流程[下]:管道是如何构建起来的? 在<中篇>中,我们对管道的构成以及它对请求的处理流程进行了详细介绍,接下 ...

随机推荐

  1. Codeforces 1000G Two-Paths 树形动态规划 LCA

    原文链接https://www.cnblogs.com/zhouzhendong/p/9246484.html 题目传送门 - Codeforces 1000G Two-Paths 题意 给定一棵有 ...

  2. scrapy 日志一般配置

  3. 1402 后缀数组 (hash+二分)

    描述 后缀数组 (SA) 是一种重要的数据结构,通常使用倍增或者DC3算法实现,这超出了我们的讨论范围.在本题中,我们希望使用快排.Hash与二分实现一个简单的 O(n log^2⁡n ) 的后缀数组 ...

  4. HDU 4614 Vases and Flowers 【线段树】+【二分】

    <题目链接> 题目大意: 有n个花瓶,每个花瓶中只能放一朵花.两种操作,一种是从A开始放F朵花,如果有的花瓶中已经有花则跳过这个花瓶,往下一个花瓶放:第二种是将区间[A,B]之间花瓶中的花 ...

  5. CSS3-flex弹性布局之flex属性

    flex属性 前置

  6. WCF、WebAPI、WCFREST、WebService、WPF之间的区别

    在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API.在.net平台下,你有很多的选择来构建一个HTTP Services.我分享一下我对 ...

  7. WPFToolkit DataGrid 使用介绍zz

      首先:这版本需要.NetFrameWork SP1的支持 WPF Toolkit - February 2010 Release 下载地址:http://wpf.codeplex.com/rele ...

  8. Vue项目初始

    利用npm搭建Vue项目流程 安装 第一步: 官方下载node 或者pip install node 第二步:可忽略 :  npm install npm@latest -g 更新最新的稳定版本 第三 ...

  9. BZOJ.4337.[BJOI2015]树的同构(树哈希)

    BZOJ 洛谷 \(Description\) 给定\(n\)棵无根树.对每棵树,输出与它同构的树的最小编号. \(n及每棵树的点数\leq 50\). \(Solution\) 对于一棵无根树,它的 ...

  10. SSM项目搭建

    1.新建包 com.javen.controller com.javen.service com.javen.dao com.javen.domain com.javen.mapper 2.log4j ...