目录

  • 前言:
  • 一、创建ABP应用的方式
  • 二、运行基于ABP的控制台应用
  • 三、运行基于ABP的Web应用
  • 四、Abp中的注入
  • 五、模块的生命周期
  • 参考文档

前言:

本文使用 .NET Core SDK 3.1 的版本。ABP Framework 在2013年就有了,至今为止出现过很多版本, 在.NET Core出现后,ABP 也发生了巨大的改变,当前版本早期为了与之前的版本进行区分叫做 Abp vNext, 现在Abp vNext已经成熟可以商用了,vNext 就不再存在,实际上他的名字就叫 ABP Framework。

一、创建ABP应用的方式

创建ABP应用有三种方式:

  1. 使用ABP的模板,按照官网指示安装 ABP CLI,使用 ABP CLI 创建项目
  2. 使用ABP的模板,直接在官网填写基本信息直接下载
  3. 在 Visual Studio 中创建 ASP.NET Core 新项目,引入 ABP 相关的包。 如果是快速开发可以使用 ABP 的模板,因为生成的项目比较复杂。如果想深入定制手动创建项目再引入 ABP 相关的包比较好。

二、运行基于ABP的控制台应用

创建一个基于 .NET Core 的控制台应用,可通过 Visual Studio 创建,也可以使用命令行创建。

> dotnet new console -n HelloAbp

引入所依赖的NuGet包,Microsoft.Extensions.DependencyInjection 和 Volo.Abp.Core。

> dotnet add package Microsoft.Extensions.DependencyInjection -v 5.0.1
> dotnet add package Volo.Abp.Core -v 4.3.3

一个Abp应用就至少需要一个模块,在Abp里面模块是以类的形式表现的, 创建一个名为 HelloAbpModule 的类,继承 AbpModule 类,这就是所谓的模块。

public class HelloAbpModule : AbpModule
    {       
    }

模块本身是没有业务逻辑的,所以我们需要一个服务。 由于Abp使用了依赖注入,要在Abp中使用服务,就需要对相应的服务进行注册。 不过有些内容不需要我们手动注册,Abp可以按照约定去注册常见的服务类型,Abp可以通过接口实现自动注册。 创建一个 HelloAbpService.cs 服务,并实现 ITransientDependency 接口,使其在程序启动时自动注册。

public class HelloAbpService : ITransientDependency
    {
        public void Run() => Console.WriteLine("Hello Wordld");
    }

修改 Main 函数使程序能够按照我们想要的方式执行。

static void Main(string[] args)
    {
        // 一个模块类代表一个模块,在一个项目里一般只有一个模块类,
        // 通过启动模块来创建Abp的应用对象
        var app = AbpApplicationFactory.Create<HelloAbpModule>();
        // 初始化Abp应用对象 
        app.Initialize();
    
        // 在应用对象的服务容器中拿到业务服务类
        // 需要安装 Microsoft.Extensions.DependencyInjection 依赖注入的包
        var service = app.ServiceProvider.GetService<HelloAbpService>();
        service.Run();
    }

三、运行基于ABP的Web应用

创建一个基于 .NET Core 的 ASP.NET Core Web API 项目,可通过 Visual Studio 创建,也可以使用命令行创建。

> dotnet new webapi -n Sample.Abp

引入所依赖的NuGet包 Volo.Abp.AspNetCore.Mvc。

> dotnet add package Volo.Abp.AspNetCore.Mvc -v 3.3.2

创建一个Abp的模块作为启动模块 AppModule 并继承 AbpModule,

public class AppModule : AbpModule
    {
    }

由于现在是基于Abp框架, 中间件管道的配置就不在Startup中配置了,而是转移到启动模块中进行配置。 如果要在启动模块中进行配置管道, 那么还需要为启动模块添加它所依赖的其他模块,通过特性 DependsOn 定义模块间的依赖关系

// 通过特性添加当前模块所依赖的其他模块 
    [DependsOn(typeof(AbpAspNetCoreMvcModule))]
    public class AppModule : AbpModule
    {
    	// TODO:
    }

管道的配置在应用启动时进行, 在AbpModule中有一个名为 OnApplicationInitialization 的应用初始化方法, 一般在该方法中配置中间件管道 我们需要在AppModule中复写他,

public class AppModule : AbpModule
    {
        public override void OnApplicationInitialization(
            ApplicationInitializationContext context)
        {
            var app = context.GetApplicationBuilder();
            var env = context.GetEnvironment();
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }

而现在的 Startup 职责是初始化Abp,

public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddApplication<AppModule>();
        }

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

完成Abp框架的配置后,之后的开发基本完全一样。 如果想创建一个控制器,现在是继承 AbpController 而不是 ControllerBase, 由于使用了Abp的控制器,把管道中配置终结点的方法删掉换为Abp的提供的终结点方法。

public override void OnApplicationInitialization(
            ApplicationInitializationContext context)
        {
            var app = context.GetApplicationBuilder();
            var env = context.GetEnvironment();
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseRouting();
            app.UseAuthorization();
            // 替换默认的终结点
            app.UseConfiguredEndpoints();
        }

添加一个 基于 AbpController 的 Action。

public class HomeController : AbpController
    {
        public IActionResult Index()
        {
            return Content("Hello World");
        }
    }

本地启动项目,访问 ~/home/index 即可得到 Hello World 。

四、Abp中的注入

自动注入服务需要实现对应的接口,例如瞬时的需要实现 ITransientDependency,而另外两个是 IScopedDependency 和 ISingletonDependency。

public class HelloAbpService : ITransientDependency
    {
        public void Run() => Console.WriteLine("Hello Wordld");
    }

或者使用特性

[Dependency(ServiceLifetime.Transient)]
    public class HelloAbpService
    {
        public void Run() => Console.WriteLine("Hello Wordld");
    }

手动注入和 ASP.NET Core 一样,依旧是在 IServiceCollection 对象中注入配置, 不过配置注入的位置不一样,需要重写 AbpModule 的 ConfigureServices 方法。

public class HelloAbpModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.AddTransient<HelloAbpService>();
            // context.Services.AddScoped<HelloAbpService>();
            // context.Services.AddSingleton<HelloAbpService>();
        }
    }

五、模块的生命周期

abp 框架打包docker abp开发框架 不选择_ASP.NET Core

一个模块的生命周期可以粗略分为 模块配置、模块初始化和模块销毁,如上图所示可以重写相应的方法。

在 ASP.NET Core 的 Startup 中的 ConfigureServices 与 AbpModule 的 ConfigureServices 相对应,

而 Startup 中的 Configure 与 AbpModule 的 OnApplicationInitialization 相对应。

关于模块的依赖关系 一个模块可能依赖于多个其他的模块,而他们之前的依赖关系决定了模块的加载和启动顺序,在Abp中使用了拓扑排序算法来计算模块的加载顺序。

启动流程

  1. 注册ABP基础设施与核心服务
  2. 加载整个应用的所有模块,按照依赖进行排序
  3. 按顺序遍历所有模块,执行每一个模块的配置方法(3个)
  4. 按顺序遍历所有模块,执行每一个模块的初始化方法(3个)

参考文档

ABP Framework - Open Source Web Application Framework