ABP VNext系列(一)-第一个ABP VNext

ABP VNext系列(一)-第一个ABP VNext

下一篇 : ABP VNext系列(二)-详解ABP的依赖注入

一. ABP VNext基本介绍

1. 什么是ABP VNext?

1. ABP框架全称为“ASP.NET Boilerplate Project”,中文翻译为“ ASP.NET样板项目”
2. 是由国外的十几名顶级架构师共同创立并开源到github(https://github.com/aspnetboilerplate)的
3. 目的是为了让.net 开发着能拥有一套开箱即用的项目架构.
4. 内部整合了一些常用的功能,比如orm、缓存、日志等等功能,让框架的使用者只需要关注业务逻辑,
    而不需要关注其他多余的中间件功能
5. 上面介绍的是ABP,但是ABP VNext是啥呢?ASP.NET Boilerplate Project是基于.net framework开发的,
    而ABP VNext则是作为.net core为基础的延申框架.
6. 总的来说就是,
	ASP.NET Boilerplate Project是.net framework的版本框架,
	ABP VNext是.net core版本的框架
7. ABP VNext:
		github: https://github.com/abpframework/abp
		官方文档: https://docs.abp.io/en/abp/latest

2. 用还是不用ABP VNext?

1. 至于为什么要用ABP VNext,博主也只能根据自身的使用经验来稍稍总结一下
2. 使用经验来看:
	2.1 框架本身是按照DDD(领域驱动)来设计的,那么咱们再接入的过程中也*可以*按照DDD的思想来开发自己的
	      项目,利于后期项目的维护
	2.2 这是一个模块化的框架,以模块来分基础功能.比如缓存模块,orm模块,就做到要啥拿啥的那种效果
	2.3 代码量来说的话,再某些方面极大的减少了我们的代码量,比如对数据库的单表的增删查改方法内置了
	      都不需要自己写,直接用就行.但是在另一方面也会增加咱们的代码量.
	      2.3.1 比如aotumapper的配置
	      2.3.2 dto类的原来越多
	      2.3.4 一个很简单没有任何逻辑可言的查询都需要service+repository双层的接口和实现
	2.4 业内通用功能不需要自己开发,只需要接入即可,很方便
3. 介绍不完了,反正这个框架有利有弊,需要自己平衡使用.但是针对微服务场景,ABP VNext能达到意想不到的效果
4. 并且这个是一个完整的大的框架,有一定的学习成本.而且如果用不好也会出问题.所以是否使用还是取决于自己.

二. 创建基于ABP VNext的项目

1. 使用之前需要掌握的技术

1. .net core肯定是必须的,博主会基于.net core 3.1的版本来介绍
2. ioc这个概念要知道是啥,并且工作中用到过,如果知道原理更佳.
3. .net core的IServiceCollection/ IServiceProvider的正确理解
4. ABP项目的一个完整的生命周期:
	3.1 ABP项目和咱们普通的项目不一样,他是包含一个自己的运行生命周期的
	3.2 步骤大概是: 生命周期开始前的配置 --> 生命周期配置完成后的初始化 --> 
							  生命周期初始化完成后稳定运行 --> 生命周期结束
    3.3 这么介绍有点太抽象,难以理解.不过不影响接下来的步骤进行,只需要大概知道有这么个东西存在即可
    3.4 ABP项目的生命周期是以一个[模块]为基础的,那么每一个项目都是一个模块,并且有一个启动模块
5. 博主下面的三个实例需求场景:
    4.1 有一个接口ITest,包含一个RunAsync()的方法.
    4.2 Test实现类继承ITest接口并打印点东西
    4.3 基于ABP项目运行并调用RunAsync()方法
6. 下面博主就来借助下面三种项目类型来完成一个最小化的ABP项目,包含一个ABP项目的完整生命周期

----这个作为咱们下面项目的简单接口和实现类

public interface ITest
{
   Task RunAsync(string str);
}
public class Test : ITest
{
   public async Task RunAsync(string str)
   {
       Console.WriteLine($"[接收打印]:{str}");
       await Task.CompletedTask;
   }
}

2. 控制台宿主

  1. 基于上面的接口和实现来,咱们先来考虑一个场景
  2. 假设我们需要在Console控制台调用此方法,正常情况下是一个什么样的流程.如下图

在这里插入图片描述

  1. 上面就是最基本的调用方式,那么我说过ABP是有一套自己独立的生命周期的,那么接下来我们看看
    ABP需要怎么做
    3.1 首先我们需要引入ABP相关的包 Volo.Abp.Core(核心包)Volo.abp.Autofac(Ioc容器包)
    因为项目是基于.net core 3.1的,所以包的版本都是3.3.2
    3.2 上面简单介绍过,ABP是一个模块化的框架,并且ABP生命周期启动是依赖于一个独立的启动
    模块的,所以接下来我们要为控制台创建一个启动模块
//1. 模块其实对应的就是一个继承于 AbpModule的一个普通类 
//2. AbpModule是Volo.Abp.Core包里面的一个核心类
//3. 由于我们需要用到Autofac,需要引用一下Autofac的模块
	[DependsOn(typeof(AbpAutofacModule))]
//4. 就这样,控制台的启动模块我们就写完了,是不是很简单
[DependsOn(typeof(AbpAutofacModule))]
public class TestModule : AbpModule
{ 
}
  1. 到这一步,或许大家有疑问了,一个空类有啥作用?为啥需要这个东西?别着急,后面的文章将会详细的介绍[模块类]
  2. 接下来我们来看看怎么用ABP来完成上面的接口调用
******注意*****
//此时需要在Test实现类后面继承一个ITransientDependency接口
public class Test : ITest, ITransientDependency

static async Task Main(string[] args)
{
	//1.这行代码就是创建一个ABP的应用的标准代码
	//2.返回的是一个ABP应用的对象
	//3.其中`UseAutofac()`扩展方法是为了帮我们实现自动注册接口
	//4.ITransientDependency 就是一个协助自动注册的约定接口
	using var application = AbpApplicationFactory.Create<TestModule>(options => options.UseAutofac());
	
	//上面代码拿到一个ABP应用对象之后需要对这个进行初始化
	application.Initialize();
	
	//1.初始化成功之后,通过下面方法可以拿到我们的接口对象
	//2.ServiceProvider其实就是.net core中的IServiceProvider对象
	//3.GetRequiredService<T>()方法可以帮我们拿到注册的接口对象
	var test = application.ServiceProvider.GetRequiredService<ITest>();
	
	//1.拿到ITest对象之后就可以直接执行了
	//2.运行之后会发现和预期结果是一致的
	await test.RunAsync("111");
}
  1. 到这里,我们就完整的创建了一个控制台宿主的ABP应用程序

3. WokerService宿主(后台服务项目)

//这个是咱们一个服务项目创建出来之后的初始代码,很简单的逻辑
public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>();//将woker类设置为启动项目
                });
//1. 首先还是要创建一个模块类,继承AbpModule,并引用Autofac模块
//2. 重写一个方法,并将Program类中的AddHostedService方法移到这里来
//3. 这样我们的启动模块就完成了
//4. 但是改造还没结束...
[DependsOn(typeof(AbpAutofacModule))]
public class WorkerHostModule : AbpModule
{
  public override void ConfigureServices(ServiceConfigurationContext context)
  {
      context.Services.AddHostedService<Worker>();
  }
}
//改造我们我们Program中的方法,让其接入ABP的生命流程管理
public static void Main(string[] args)
{
      //1. 获取build对象,不要直接调Run()方法,目的是为了,并且初始化
      var build = CreateHostBuilder(args).Build();
      //2. 拿到ABP应用的对象 
      var application = build.Services.GetRequiredService<IAbpApplicationWithExternalServiceProvider>();
      //3. ABP应用初始化,执行Initialize
      application.Initialize(build.Services);
      //4. 调用Run()方法使程序跑起来
      build.Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
       Host.CreateDefaultBuilder(args)
           .ConfigureServices((hostContext, services) =>
           {
              //这里需要将启动类配置进行后置 -->到模块类中
              services.AddApplication<WorkerHostModule>();
           })
           .UseAutofac();//引用Autofac
//接下来改造我们的Worker类
public class Worker : BackgroundService
{
    private readonly ITest _test;//注入我们的ITest接口

    public Worker(ITest test)
    {
        this._test = test;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (true)
        {
            //直接调用即可
            await this._test.RunAsync(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            await Task.Delay(500, stoppingToken);
        }
    }
}

在这里插入图片描述

4. Web宿主

  1. 创建一个空的api项目,并引入Volo.Abp.AspNetCore.MvcVolo.abp.Autofac
  2. 继续创建一个模块启动类
//1. 这次我们需要多引用两个模块
//2. 重写一个方法,把原来的Startup类中的方法拿到这里来,并删除多余的
[DependsOn(
        typeof(AbpAutofacModule),
        typeof(AbpAspNetCoreModule),
        typeof(AbpAspNetCoreMvcModule)
        )]
    public class WebHostModule : AbpModule
    {
        /// <summary>
        /// abp 模块初始化
        /// </summary>
        /// <param name="context"></param>
        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            var app = context.GetApplicationBuilder();
            var env = context.GetEnvironment();
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseRouting();
            app.UseConfiguredEndpoints();
        }
    }
  1. 改造Program类
 public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                })
                .UseAutofac();//只是增加了这一行代码
  1. 改造Startup类
public class Startup
    {
       
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
        	//添加一个ABP模块应用
            services.AddApplication<WebHostModule>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
        	//1. 多余方法全部移除或者放到WebHostModule中初始化
        	//2. 调用app的初始化方法
        	//3. 这个类改造比较固定
            app.InitializeApplication();
        }
    }
  1. 改造一下Test
public class Test : ITest, ITransientDependency
    {
    	//这里我们返回一个字符串,方便Api测试
        public async Task<string> RunAsync(string str)
        {
            await Task.CompletedTask;
            return $"[接收打印]:{str}";
        }
    }
  1. 控制器
[ApiController]
    public class TestController : ControllerBase
    {
        private readonly ITest _test;//注入我们的方法

        public TestController(ITest test)
        {
            this._test = test;
        }

        [HttpGet]
        [Route("home/get")]
        public async Task<IActionResult> Get(string str)
        {
        	//通过api来测试是否正常
            return new JsonResult(await this._test.RunAsync(str));
        }
    }
  1. 运行

在这里插入图片描述

  1. 到这里,我们web项目也集成了ABP

三. 总结

1. 此测试实例代码放在 https://gitee.com/jerryow/abp-practice
2. 此文介绍的是最小化的ABP应用,但是工作中是基于DDD的分层架构来搭建多层项目的,所以这个实例仅仅
	是为了帮助入门理解而已
3. ABP帮助我们进行了约定式的Ioc注册.比如我们的ITest接口的获取是并没有手动注册到容器的,
	而是通过在实现类中继承了一个ITransientDependency的接口就实现了自动注册.
4. 博主之前的文章有开启一个基于ABP VNext的微服务架构系列文章,但是写到第二节发现,并不适合所有人阅读.
	因为涉及到的内容实在是太多了,比如:
	4.1 ABP框架的应用和各个应用模块的使用
	4.2 微服务架构中的相关中间件: 网关、服务发现注册、配置中心、缓存、消息队列、认证授权中心、日志等
	4.3 微服务架构中的部署相关: git、jenkins、docker、k8s
	4.4 微服务架构中的性能监控: promethus、skywalking
5. 众多原因让博主不得不放弃直接继续写那个文章,所以博主改变了方式,会先介绍这些相关的组件还有
	聚焦到ABP框架的本身
6.最后再进行基于ABP VNext的微服务架构系列文章的完善.
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值