简介

模块化的介绍一共2篇

这一篇我们实现一个功能非常简单的StartupModules模块化。

第二篇我们来实现一个ABP的模块化效果。

思考

其实来简单想一下模块化的实验思路,写个接口=>模块类继承该接口=>项目启动反射检索=>调用接口实现。

那么具体到代码实践应该怎么写呢。

开始

第一步

第一步就是写一个模块化接口类的嘛!

新建类 IStartupModule

然后写一个反射检索全文谁继承了这个接口的方法

新建类 StartupModulesOptions



代码解释: Activator.CreateInstance 与指定参数匹配程度最高的构造函数来创建指定类型的实例

ps:白话文就是,你给我Type我给你创建个对应的实例

更一个有意思的是 Assembly.GetEntryAssembly()! 这个! 是不是很好奇怕

ps:我第一次看到这个语法也蒙了,问了好多人大家都没用过,这个语法同TS中的断言,是非null类型断言,意思就是我断言我这个方法返回的内容绝对不是null。

第二步

到这里来看我们是不是已经拿到了所有继承接口的模块那么怎么在该调用的地方调用呢,缺啥写啥

第三步

运行代码也有了,我该怎么调用呢。

接下来只要在 在Program 的 WebHost 调用.UseStartupModules() 流程就可以加载我们的 ConfigureServices 了

中间来插播一下

请让我掏出来一个器大的东西来说 他就是: IStartupFilter ,这个东西是个啥东西呢。来看一段源码

namespace Microsoft.AspNetCore.Hosting
{
public interface IStartupFilter
{
Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next);
}
}

这里我们看到了 Configure 他返回一个 IApplicationBuilder 他是怎么用的呢

我们新建一个空的Web项目的时候不知道有没有注意过 UseStaticFiles 这个函数

 public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles();
app.UseRouting(); app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
});
}

在这个方法中,你可以直接使用方法提供的IApplicationBuilder参数,并且可以向其中添加各种中间件。使用IStartupFilter, 你可以指定并返回一个Action类型的泛型委托,这意味你除了可以使用方法提供的泛型委托配置IApplicationBuilder对象, 还需要返回一个泛型委托。

我们来看一段代码 Build(); 这个会调用BuildApplication方法

public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build(); host.Run();
}
} private RequestDelegate BuildApplication()
{
..
IApplicationBuilder builder = builderFactory.CreateBuilder(Server.Features);
builder.ApplicationServices = _applicationServices; var startupFilters = _applicationServices.GetService<IEnumerable<IStartupFilter>>();
Action<IApplicationBuilder> configure = _startup.Configure;
foreach (var filter in startupFilters.Reverse())
{
configure = filter.Configure(configure);
} configure(builder); return builder.Build();
}

首先,此方法创建IApplicationBuilder的实例,该实例将用于构建中间件管道,并将ApplicationServices设置为已配置的DI容器。

接下来的代码块很意思。首先,从DI容器中获取了一个集合IEnumerable<IStartupFilter>

我们可以配置多个IStartupFilter来形成一个管道,所以这个方法只是从容器中取出它们。

现在我们通过循环遍历每个IStartupFilter(以相反的顺序),传入Startup.Configure方法,然后更新局部变量configure来创建Configure方法的管道。

第四步

我们自己如何来实现 一个IStartupFilter 让他帮我们调用 Configure。

第五步

在 WebHostBuilderExtensions类 UseStartupModules 方法 ConfigureServices 下用 IStartupFilter 注入实现

这样在Build() 的时候就会调用模块的方法了

ActivatorUtilities.CreateInstance<ModulesStartupFilter>(sp, runner) // 第二个参数是在创建实例的时候 给构造函数注入的第一个参数

测试一下

新建 Core Web项目 在 Program.cs
 Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
// 进行模块映射
webBuilder.UseStartupModules().UseStartup<Startup>();
});

在 Startup.cs ConfigureServices和Configure 下打一个 Console.WriteLine

新建 类 HangfireStartupModule 继承 IStartupModule
public class HangfireStartupModule : IStartupModule
{
public void ConfigureServices(IServiceCollection services)
{
Console.WriteLine("HangfireStartupModule----ConfigureServices");
}
public void Configure(IApplicationBuilder app)
{
Console.WriteLine("HangfireStartupModule----Configure");
}
}
结果

一个非常简单的模块化就完工了,当然这个是基础版本,只能拿来借鉴思路学习下。

补充模块的 ConfigureServices 和 Configure 传递上下文

新建类 ConfigureServicesContext 和 ConfigureMiddlewareContext

  public class ConfigureMiddlewareContext
{
public ConfigureMiddlewareContext(IConfiguration configuration, IWebHostEnvironment hostingEnvironment, IServiceProvider serviceProvider, StartupModulesOptions options)
{
Configuration = configuration;
HostingEnvironment = hostingEnvironment;
ServiceProvider = serviceProvider;
Options = options;
} public IConfiguration Configuration { get; } public IWebHostEnvironment HostingEnvironment { get; }
public IServiceProvider ServiceProvider { get; } public StartupModulesOptions Options { get; }
} public class ConfigureServicesContext
{
public ConfigureServicesContext(IConfiguration configuration, IWebHostEnvironment hostingEnvironment, StartupModulesOptions options)
{
Configuration = configuration;
HostingEnvironment = hostingEnvironment;
Options = options;
} public IConfiguration Configuration { get; }
public IWebHostEnvironment HostingEnvironment { get; }
public StartupModulesOptions Options { get; }
}

修改 StartupModuleRunner 的方法

 public void ConfigureServices(IServiceCollection services, IConfiguration configuration, IWebHostEnvironment hostingEnvironment)
{
var ctx = new ConfigureServicesContext(configuration, hostingEnvironment, _options);
foreach (var cfg in _options.StartupModules)
{
cfg.ConfigureServices(services, ctx);
}
} public void Configure(IApplicationBuilder app, IConfiguration configuration, IWebHostEnvironment hostingEnvironment)
{
using (var scope = app.ApplicationServices.CreateScope()) {
var ctx = new ConfigureMiddlewareContext(configuration, hostingEnvironment, scope.ServiceProvider, _options); foreach (var cfg in _options.StartupModules)
{
cfg.Configure(app, ctx);
}
} }

鸣谢

玩双截棍的熊猫、NETCore-大黄瓜

思路来源:https://github.com/henkmollema/StartupModules

知识全聚集 .Net Core 技术突破 | 如何实现一个模块化方案一的更多相关文章

  1. 知识全聚集 .Net Core 技术突破 | 我用C#手把手教你玩微信自动化一

    知识全聚集 .Net Core 技术突破 | 我用C#手把手教你玩微信自动化一 教程 01 | 模块化方案一 02 | 模块化方案二 03 | 简单说说工作单元 其他教程预览 分库分表项目实战教程 G ...

  2. 知识全聚集 .Net Core 技术突破 | 简单说说工作单元

    知识全聚集 .Net Core 技术突破 | 简单说说工作单元 教程 01 | 模块化方案一 02 | 模块化方案二 其他教程预览 分库分表项目实战教程 Git地址: https://github.c ...

  3. 知识全聚集 .Net Core 技术突破 丨ABP vNext 开始

    介绍 很久没有更新博客了,之前想更新但是发现博客园崩了,外加工作上的调换也比较忙,最近有了点时间我来继续更新下这个系列的文章. 今年3月份我带着我们研发组同事,将公司产品从老Abp重构到Abp vNe ...

  4. 34张史上最全IT架构师技术知识图谱 最新下载

    本文是笔者多年来积累和收集的知识技能图谱,小编极力推荐分享给身边的技术人儿,希望这份技术知识图谱能够帮助到每一位奋斗在技术路上的小伙伴. 下面是笔者多年来积累和收集的知识技能图谱,有的是笔者原创总结的 ...

  5. 【HMS Core 6.0全球上线】Network Kit全链路网络加速技术,应用无惧网络拥塞

    HMS Core 6.0已于7月15日全球上线,本次版本向广大开发者开放了众多全新能力与技术.其中HMS Core Network Kit开放了全链路网络加速技术,助力开发者为用户提供低时延的畅快网络 ...

  6. In-Cell、On-Cell和OGS全贴合屏幕技术区别

    昨天刚发布的小米3用的是OGS全贴合屏幕技术,包括魅族MX3也是同样的技术,但是iPhone5是In-Cell屏幕技术,什么才是全贴合?它们之间到底有何区别?哪个好?小编今天就来普及一下全贴合屏幕技术 ...

  7. 基于Kubernetes 构建.NET Core技术中台

    今天下午在腾讯云+社区社区分享了<基于Kubernetes 构建.NET Core技术中台>,下面是演讲内容的文字实录. 我们为什么需要中台 我们现在处于企业信息化的新时代.为什么这样说呢 ...

  8. 2019亚太内容分发大会,阿里云获CDN领袖奖、技术突破奖

    近日,亚太CDN产业联盟主办的2019亚太内容分发大会在上海召开.本次大会以"5G分发"为主题,集结了CDN领域近千名行业领袖.专家参与.在会上,阿里云斩获“CDN领袖奖”.“技术 ...

  9. 基于Kebernetes 构建.NET Core技术中台

    原文:基于Kebernetes 构建.NET Core技术中台 我们为什么需要中台 我们现在处于企业信息化的新时代.为什么这样说呢? 过去企业信息化的主流重心是企业内部信息化.但现在以及未来的企业信息 ...

随机推荐

  1. kolla build 配置

    kolla-build.conf 配置文件: [DEFAULT] debug = false base = centos base_tag = 7.7.1908 base_arch = x86_64 ...

  2. Docker系列——Docker安装&基础命令

    Docker 概述 Docker 是一个开源的应用容器引擎,Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化. ...

  3. 计算机网络-应用层(1)Web应用与HTTP协议

    Web 页面(Web page,也叫文档)是由对象组成的. 对象:HTML文件.JPEG图片.视频文件.动态脚本等,通过一个URL地址寻址.每个URL地址由存放对象的服务器主机名和对象的路径名组成. ...

  4. 第一篇 Scrum冲刺博客

    一.Alpha任务认领 冯荣新 任务 预计时间 搜索框 0.5h 首页轮播图 0.5h 分类导航 2h 商品列表 2h 商品详情轮播图 0.5h 商品底部工具栏 1h 购物车列表 1.5h 购物车工具 ...

  5. latex在线帮助文档

    1.ctex官方网站 http://www.ctex.org/HomePage 2.在线帮助文档 http://www.ctex.org/OnlineDocuments

  6. 完美解决方案-雪花算法ID到前端之后精度丢失问题

    最近公司的一个项目组要把以前的单体应用进行为服务拆分,表的ID主键使用Mybatis plus默认 的雪花算法来生成. 快下班的时候,小伙伴跑过来找我,:"快给我看看这问题,卡这卡了小半天了 ...

  7. 使用xShell 连接 docker 使用说明

    方式一:当不知道docker里镜像的root密码的时候 1.从Docker Hub下载需要的镜像 docker pull 镜像名字 2.使用docker run命令启动容器 docker run -i ...

  8. 焦大:seo思维进化论(上)

    http://www.wocaoseo.com/thread-51-1-1.html seo排名浮动一直是很多人关心的事情,但是背后的原理却一直很少被人知道.在seo是什么里说了seo的核心是什么,我 ...

  9. 【经验分享】用adb揪出安卓APP弹窗广告的原形

    背景 相信不少安卓用户中过影子弹窗广告的困扰,这种推广APP本体在后台运行,而且可以在其他APP上弹出覆盖广告,一不小心就会误操作,点击广告或者下载APP,着实令人恶心. 以前的广告软件只在通知栏会推 ...

  10. three.js尝试(二)模拟游戏开发:3D人物在地图上行走

    本次尝试,模拟了一个小人物在场景中行走,使用简单模型建立了森林,图片纹理模拟草地,加载3D模型呈现人物,使用按键asdw模拟人物的行走,行走和站立时人物的切换等. 主要用到点:3D模型的加载,模型的动 ...