ABP(一):入门基础篇

ABP官网:https://www.abp.io/

ABP GitHub:https://github.com/abpframework/abp

要学习ABP,第一手资料肯定是官方文档,详细信息也请查看官方文档。

基本概念

ABP vNext(以下简称ABP)的前身是asp.net boilerplate(老版abp),它不是一个简单的版本更新,而是完全基于.NET Core的重写,废话不多说,来到这里你至少是知道ABP的。

ABP是一个开源应用程序框架,专注于基于ASP.NET Core的Web应用程序开发,但也支持开发其他类型的应用程序。

计划从基础搭建开始,逐步把涉及到的东西都走一遍,这将会是一个持续更新的系列文章。

本篇核心:

  • 模块化(Modularity)
  • 依赖注入(Dependency Injection)

使用ABP开发新项目的最简单方法是使用启动模板,但我不打算这么干,我更想知道abp是怎么启动的,我们不仅要知其然,更要知其所以然。

那么我们从一个空项目开始,手动安装abp框架。

ABP开发.Net Core Console应用程序

1、使用Visual Studio创建一个新的.Net Core Console应用程序,就叫MyFirstAbpConsole。

2、添加引用Volo.Abp.Core

下面我们就引入abp的第一个重要的概念,模块化(Modularity),abp是一个模块化的框架,一个abp框架至少要包含一个模块(从AbpModule类派生的模块类),即启动模块或者叫根模块。

3、创建一个模块类MyFirstAbpConsoleAppModule,并继承自AbpModule,这样一个模块就有了,暂时我们什么也不做,如下所示:

4、回到Program类的Main方法中,我们来启动abp。

abp框架中提供了一个应用程序工厂类,用于创建启动模块,代码如下:

 这样我们就创建并启动了我们的模块应用并且完成了初始化。

4、新建一个HelloWorldService的服务类,里面定义了一个SayHello的方法,代码如下:

 那么我们怎么调用我们的这个服务呢,这里又引入了一个重要的概念,依赖注入(Dependency Injection)。

在abp中,服务都会被注册到容器中,在需要用到时注入该服务。

首先,把服务注册到容器中,我们暂时先说一种方式,即继承自ITransientDependency接口(瞬态的,不同生命周期后面再说),框架会自动把服务注册到容器中

代码如下:

 5、获取服务并调用服务输出Hello World

回到Program类的Main方法,前面我们应用已经创建并初始化完成,接着我们调用服务如下:

这里我们使用了IServiceProvider接口来获取服务,在abp中注入服务的方式有多种,后面再说。 

6、运行程序,结果输出Hello World 说明整个程序框架运行成功。

总结:

  • abp是一个基于模块化的框架,启动并运行abp框架,至少要包含一个启动模块
  • abp中的服务都是通过注入的方式调用,需要某个服务时不再需要new
  • abp中的自动注册服务的接口有三个,区别是生命周期不同,分别是ITransientDependency、IScopedDependency和ISingletonDependency

下面我们来改造下上面的依赖注入,我们来使用Autofac手动注册服务

第一步,添加Volo.Abp.Autofac引用

 第二步,回到MyFirstAbpConsoleAppModule模块类,添加依赖项,把Autofac模块添加到当前模块中来(abp是基于模块化的,所以Autofac对于abp来说也是一个模块)

第三步,原先的 HelloWorldService继承的接口ITransientDependency将不再需要,我们来使用Autofac手动把HelloWorldService注入到当前模块中,需要我们来重写AbpModule中的ConfigureServices虚方法,代码如下:

 第四步,创建模块的代码也要修改下,增加一个options操作,使用Autofac,如下:

 第五步,我们再次运行程序,结果输出Hello World 没有问题。

至此,我们知道了如何创建一个abp的模块、初始化应用、创建服务、注册服务以及如何注入服务的一个最简单流程。

本次内容的重点是理解模块化、依赖注入两个知识点,这两点真的很重要,我们再展开聊聊

第一点:abp把应用进行了模块化,每个模块里定义自己的服务,并在它自己的独立模块类中通过依赖注入进行注册。

public class SomeModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        //在这里注册依赖项
    }
}

比如上面我们使用Autofac框架时,Autofac本身自己就是一个独立模块,然后我们使用它,就引入它,并且注册到我们的模块中,就是这么个意思

abp框架很庞大,但是不臃肿,因为我们按需分配,我们只引入并注册的是我们需要的。

 第二点:abp的依赖注入系统,是基于微软的 dependency injection extension 库(Microsoft.Extensions.DependencyInjection nuget package)开发的,因此,它的文档在abp中也是有效的。

abp框架提供了多种注册方式,主要是两大类,一种是按约定的自动注册,一种是手动注册。这里简单讲一下,详细可以看官方文档。

常规注册

abp引入了常规服务注册,你不需要按照约定去做任何事情去注册一个服务,它是自定完成的。如果你想禁用它,你可以通过重写PreConfigureServices方法设置SkipAutoServiceRegistration = true即可。一旦跳过自动注册,你就应该手动的注册你的所有的服务,在这种情况下,扩展方法AddAssemblyOf能够帮助你按照约定注册你的所有服务,看个例子:

public class AppModule : AbpModule
{
    public override void PreConfigureServices(ServiceConfigurationContext context)
    {
        SkipAutoServiceRegistration = true;
    }

    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        context.Services.AddAssemblyOf<AppModule>();
    }
}

固有的注册类型

默认情况下,某些特定的类型已经注册到依赖注入中

比如,上面的模块类就是作为单例(singleton)注册的,无需我们手动处理。

依赖接口注册

如果你实现了这些接口,你的类就会自动的注册到依赖注入中。比如上面我们首先使用的方式就是这种方式。

  • ITransientDependency:注册为瞬态生命周期,每次调用都是一个新的实例
  • IScopedDependency:注册为一个范围内的生命周期,同一个http请求的范围内使用的同一个实例
  • ISingletonDependency:注册为单例模式,首次请求会创建这个服务,后续的所有请求都使用相同的实例,存在于整个应用程序的生命周期中。

依赖特性注册

是使用属性DependencyAttribute,例子:

[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
public class SomeService
{
    ……  
}

手动注册

也可以通过手动方式注册你需要的服务,上面已经用到了,就是在模块类中的重写配置服务的方法中手动添加,这种其实是微软的标准的注入方式。

注入依赖项

如何调用已注册的服务呢,abp提供了三种常见的方式

  • 构造函数注入,这是将服务注入类的最常见方法
  • 属性注入,这点微软是不支持的,abp可以与第三方DI提供程序(Autofac)集成,从而可以实现属性注入
  • 从IServiceProvider解析服务,即通过注入IServerProvider到类中,然后通过它来获取服务,使用的很少

关于更多的如何注册服务到容器以及将容器中的服务注入类的问题,请查看abp官方文档和微软的依赖注入的文档吧。

通过上面的内容,我们已经通过一个控制台项目了解到如何运行abp框架,以及它的一些基本概念,现在,我们将基于Asp.Net Core Web 应用,继续了解下abp框架如何在Web项目中工作。

ABP创建Asp.Net Core Web MVC应用程序

1、创建一个Asp.Net Core Web 应用程序MyFirstAbpWeb,使用空模板

2、添加引用:Volo.Abp.AspNetCore.Mvc

3、新建一个MyFirstAbpWebModule模块类,因为是.NetCore的 MVC项目,所有添加一个依赖。

using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Modularity;

namespace MyFirstAbpWeb
{
    [DependsOn(typeof(AbpAspNetCoreMvcModule))]
    public class MyFirstAbpWebModule : AbpModule
    {
    }
}

4、配置启动应用程序和初始化应用程序

4.1、打开Startup启动类,在ConfigureServices方法中增加一段代码,把刚刚新建的模块类注册进来(创建启动模块)。

public void ConfigureServices(IServiceCollection services)
{
    services.AddApplication<MyFirstAbpWebModule>(options => {
                
    });
}

4.2、配置应用程序初始化,继续修改Startup启动类,在Configure方法中增加一行代码,并且把原来的代码剪切出来

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.InitializeApplication();

}

回到模块类中,重写OnApplicationInitialization方法,把剪切的内容粘贴过来,并稍作修改

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Hosting;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Modularity;

namespace MyFirstAbpWeb
{
    [DependsOn(typeof(AbpAspNetCoreMvcModule))]
    public class MyFirstAbpWebModule : AbpModule
    {
        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            var env = context.GetEnvironment();
            var app = context.GetApplicationBuilder();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            //app.UseEndpoints(endpoints =>
            //{
            //    endpoints.MapGet("/", async context =>
            //    {
            //        await context.Response.WriteAsync("Hello World!");
            //    });
            //});
            app.UseConfiguredEndpoints();

        }
    }
}

5、配置完成后,新建一个控制器文件夹Controllers,在里面新建一个HomeController,继承自AbpController

using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc;

namespace MyFirstAbpWeb.Controllers
{
    public class HomeController : AbpController
    {
        public ActionResult Index()
        {
            return Content("Hello World");
        }
    }
}

运行后,浏览器输出Hello World

至此,我们使用了一个最基本的abp框架 ,后面我们将进入一个实战阶段

原文地址:https://www.cnblogs.com/njabsky/p/13509896.html