asp.net core-自定义service

asp.net core 结构

先看如下一张图,虚线的黑框是我们的asp.net core程序,外部通过nginx实现反向代理接收http request和response。

内部是一个内置的web服务器Kestrel和web host主机(继承自IHost),web host主机内部是我们的代码,最内部运行的是带有一个个中间件的管道。

下面是启动的流程,创建一个IHostBuilder, 然后配置WebHostBuilder的相关配置(比如监听端口,日志,kestrel或者其他的配置),然后通过Build方法来创建IHost。这时候会调用StartUp的ConfigureService(该方法用于注入服务),然后调用Ihost的Run方法来启动,框架这时会自动调用Startup.Configure方法(该方法用于配置管道的中间件)。

Kestrel的两种使用,kestrel是一个高效的,但功能简单的内置web服务器,所以它一般会跟其他web服务器搭配使用。

 

 

 

 

 

IWebHostBuilder 配置

下面通过配置url来展示显示各种方式的运行优先级,下面按优先级从低到高描述下4种配置形式

1. 通过环境变量配置

如图,通过配置LaunchSettings.json中的applicationUrl可以设置ip和端口,这个会自动在下面生成ASPNETCORE_URLS标签。

 

 

 

2. 通过编码配置

 

3. 通过应用配置

注意图中的urls标签,这个是通过应用配置。另一个ASPNETCORE_URLS是属于环境变量配置,凡是ASPNET开头的配置都是环境变量配置。

 

 

4. 通过命令行配置

命令行启动的时候有2种情况,第一种直接在项目根目录通过dotnet run运行,后面配置端口如下图

 

 第二种是通过publish之后生成了dll,如图通过dotnet命令直接运行dll

 

 

优先级的意思是,假如同时配置了以上4种,那么最终监听的端口以最后一种命令行的形式,比如9000或者7999.

自定义Service

依赖注入和控制反转相信大家一定不会陌生,任何技术的出现都不是偶然,它必定是为顺应时代而生。随着项目越来越复杂,代码量越来越多,那么代码之间的耦合性就会越多,这个时候IOC容器应运而生。

控制反转是指有一个第三方的容器,它将负责管理你需要的对象,你不再需要创建和管理你想要的对象类以及它的依赖,把创建以及生命周期的管理统统交给他。你只需要专心实现自己的功能。

依赖注入就是把你的类包括它的依赖注入到容器,然后再需要的地方通过某种方式直接拿到(可以是构造函数,接口,特性,setter)。

这一切的目的就是为了实现松耦合,可维护以及可测试。

asp.net core就有这么一个容器IServiceCollection(namespace是DependencyInjection,还有很多其他的依赖注入框架Unity,Autofac,Ninject,它们都是属于.net的,功能比DependencyInjection更加强大)

asp.net core 提供了3种方式注入

// 创建单例
services.AddSingleton();
// 创建瞬时service,每次请求实例,容器都会new一个新的实例
services.AddTransient();
// 作用域,线程单例,在同一个线程里只创建一次。
services.AddScoped();

 

好了说了这么多,进入正题,如何优雅的实现自定义service

我们可以发现,asp.net core的源码,所有的注入服务基本都是不带参数,并且是通过lambda表达式来实现配置。

这里我们通过1个例子来展示下,我们的需求是注入2个类实现,但是它们的接口是一样得,我们需要调用者通过不同的配置来调用不同的实例。

Interface和实现类就不写了,下面写MessageService的builder类,用于注入2个实现类

public class MessageServiceBuilder
{
    private IServiceCollection serviceCollection;

    public MessageServiceBuilder(IServiceCollection services)
    {
        serviceCollection = services;
    }

    public void UseEmail()
    {
        ServiceCollection.AddSingleton<IMessageService, EmailService>();
    }

    public void UseSms()
    {
        ServiceCollection.AddSingleton<IMessageService, SmsService>();
    }
}

下面就是核心了,创建一个IServiceCollection的扩展类,然后传入一个参数是MessageServiceBuilder的Action,该Action在Startup中根据所需要的对象,调用特定的方法实现注入,然后执行这个Action。

public static class MessageServiceExtension
{
    public static void AddMessage(this IServiceCollection services, Action<MessageServiceBuilder> configure)
    {
        var builder = new MessageServiceBuilder(services);
        configure(builder);
    }
}
services.AddMessage(builder => builder.UseSms());

lambda让c#成为了最优雅的语言,没有之一。

这也是源码的实现方式,另附上.net core源码,https://github.com/dotnet/core

posted @ 2021-01-06 17:33  小鸡蛋白  阅读(1419)  评论(0编辑  收藏  举报