• 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

  • 相关阅读:
    [java初探06]__排序算法的简单认识
    [java初探05]__数组的简单认识及Arrays类的常用方法
    [java工具类01]__构建格式化输出日期和时间的工具类
    [Java初探04]__字符串(String类)相关
    [Java初探实例篇02]__流程控制语句知识相关的实例练习
    【Java初探03】——流程控制语句
    iOS ipv6 被拒
    iOS工程中如何去掉第三方的警告
    iOS面试准备之思维导图(转)
    UML图基本类型
  • 原文地址:https://www.cnblogs.com/xiaojidanbai/p/14224327.html
Copyright © 2020-2023  润新知