.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. F(x) 数位dp

    Problem Description For a decimal number x with n digits (AnAn-1An-2 ... A2A1), we define its weight ...

  2. day14,函数的使用方法:生成器表达式,生成器函数

    生成器表达式: #列表推导式 # y = [1,2,3,4,5,6,7,8] # x = [1,4,9,16,25,36,49,64] # x = [] # for i in y: # x.appen ...

  3. spring的webutils包。适用于访问httpservletrequest和httpservletresponse

    WebUtils位 于 org.springframework.web.util 包中的 WebUtils 是一个非常好用的工具类,它对很多 Servlet API 提供了易用的代理方法,降低了访问 ...

  4. pyqt text browser 设置文本

    pyqt text browser 设置文本 setHtml(u"Html") setPlainText(u"纯文本") setText(u"文本\n ...

  5. oracle 中可以用 case when then else end来处理除数是0的情况

    case when a.ZJXJE != 0 then to_char(round((a.YFZK-b.YFZK)/a.ZJXJE,2)) else '本期总进项金额为零' end then和else ...

  6. Wannafly Winter Camp 2019.Day 8 div1 E.Souls-like Game(线段树 矩阵快速幂)

    题目链接 \(998244353\)写成\(99824435\)然后调这个线段树模板1.5h= = 以后要注意常量啊啊啊 \(Description\) 每个位置有一个\(3\times3\)的矩阵, ...

  7. Linux之Redis安装

    一.下载解压 1 2 3 4 ## 下载Redis wget http://download.redis.io/releases/redis-2.8.17.tar.gz ## 解压 tar zxvf ...

  8. C# Json序列化去掉k__BackingField问题的解决方案

    方案一: 如果是WebAPI,可以加入全局设置: GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettin ...

  9. 可以直接用的“ html转字符串string”方法

    //html转字符串 -(NSString *)filterHTMLString:(NSString *)html { NSScanner * scanner = [NSScanner scanner ...

  10. vue的生命周期(又称钩子函数)----以及vue1.0版本与vue2.0版本生命周期的不同

    vue生命周期 1. vue1.0版本与vue2.0版本生命周期的不同 vue1.0版本生命周期图示 图1  vue1.0版本生命周期 vue1.0版本的生命周期: init 实例创建之前 creat ...