Abp源码分析之Abp最小系统

简介: 本文详细介绍了如何构建一个基于ABP框架的最小系统,包括创建API项目、配置模块、访问数据库等步骤。通过创建API项目、修改`Program.cs`和`BookAbpModule.cs`文件,以及添加模块和数据库访问功能,最终实现了基本的CRUD操作。文章还展示了如何使用Swagger生成API文档,并通过控制台输出验证模块的加载顺序。适合初学者快速上手ABP框架。

title: Abp源码分析之Abp最小系统
authors: shiningrise
tags: [Abp]
image:

description: Abp源码分析之Abp最小系统

最小系统

创建API项目

创建API项目并安装以下依赖

修改Program.cs为以下内容

using BookApp;

var builder = WebApplication.CreateBuilder(args);

await builder.AddApplicationAsync<BookAbpModule>();

builder.Host.UseAutofac();

var app = builder.Build();

await app.InitializeApplicationAsync();

await app.RunAsync();

创建BookAbpModule.cs

using Microsoft.OpenApi.Models;
using Volo.Abp;
using Volo.Abp.Application;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Autofac;
using Volo.Abp.Domain;
using Volo.Abp.Modularity;
using Volo.Abp.Swashbuckle;

namespace BookApp
{
    [DependsOn(
        typeof(AbpAutofacModule),
        typeof(AbpAspNetCoreMvcModule),
        typeof(AbpSwashbuckleModule)
    )]
    public class BookAbpModule : AbpModule
    {
        override public void ConfigureServices(ServiceConfigurationContext context)
        {
            ConfigureSwaggerServices(context.Services);
        }


        override public void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            var app = context.GetApplicationBuilder();
            var env = context.GetEnvironment();

            app.UseStaticFiles();
            app.UseRouting();

            app.UseSwagger();
            app.UseAbpSwaggerUI(options =>
            {
                options.SwaggerEndpoint("/swagger/v1/swagger.json", "BookApp API");
            });

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

        private void ConfigureSwaggerServices(IServiceCollection services)
        {
            services.AddAbpSwaggerGen(
                options =>
                {
                    options.SwaggerDoc("v1", new OpenApiInfo { Title = "BookApp API", Version = "v1" });
                    options.DocInclusionPredicate((docName, description) => true);
                    options.CustomSchemaIds(type => type.FullName);
                }
            );
        }
    }
}

模块化编程

新建AbpModuleA类库并引用Volo.Abp.Core

//加AbpModuleAModule.cs
using System.IO;

using System;
using Volo.Abp.Modularity;
using Volo.Abp;

namespace AbpModuleA
{
    public class AbpModuleAModule: AbpModule
    {
        public override void PreConfigureServices(ServiceConfigurationContext context)
        {
            Console.WriteLine("AbpModuleA.PreConfigureServices ");
        }

        override public void PostConfigureServices(ServiceConfigurationContext context)
        {
            Console.WriteLine("AbpModuleA.PostConfigureServices");
        }

        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            Console.WriteLine("AbpModuleA.ConfigureServices");


        }

        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            Console.WriteLine("AbpModuleA.OnApplicationInitialization");

        }

        public override void OnPreApplicationInitialization(ApplicationInitializationContext context)
        {
            Console.WriteLine("AbpModuleA.OnPreApplicationInitialization");
        }
        override public void OnPostApplicationInitialization(ApplicationInitializationContext context)
        {   
            Console.WriteLine("AbpModuleA.OnPostApplicationInitialization");
        }
    }
}

新建AbpModuleB类库并引用Volo.Abp.Core

//加AbpModuleBModule.cs
using System.IO;

using System;
using Volo.Abp.Modularity;
using Volo.Abp;

namespace AbpModuleB
{
    public class AbpModuleBModule: AbpModule
    {
        public override void PreConfigureServices(ServiceConfigurationContext context)
        {
            Console.WriteLine("AbpModuleB.PreConfigureServices");
        }

        override public void PostConfigureServices(ServiceConfigurationContext context)
        {
            Console.WriteLine("AbpModuleB.PostConfigureServices");
        }

        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            Console.WriteLine("AbpModuleB.ConfigureServices");


        }

        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            Console.WriteLine("AbpModuleB.OnApplicationInitialization");

        }

        public override void OnPreApplicationInitialization(ApplicationInitializationContext context)
        {
            Console.WriteLine("AbpModuleB.OnPreApplicationInitialization");
        }
        override public void OnPostApplicationInitialization(ApplicationInitializationContext context)
        {   
            Console.WriteLine("AbpModuleB.OnPostApplicationInitialization");
        }
    }
}

修改Api项目的模块配置文件

//BookAbpModule.cs

using Microsoft.OpenApi.Models;
using Volo.Abp;
using Volo.Abp.Application;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Autofac;
using Volo.Abp.Domain;
using Volo.Abp.Modularity;
using Volo.Abp.Swashbuckle;
using AbpModuleA;
using AbpModuleB;

namespace BookApp
{
    [DependsOn(
        typeof(AbpAutofacModule),
        typeof(AbpAspNetCoreMvcModule),
        typeof(AbpSwashbuckleModule),
        typeof(AbpModuleAModule),
        typeof(AbpModuleBModule)

    )]
    public class BookAbpModule : AbpModule
    {
        public override void PreConfigureServices(ServiceConfigurationContext context)
        {
            Console.WriteLine("BookAbpModule.PreConfigureServices ");
        }

        override public void PostConfigureServices(ServiceConfigurationContext context)
        {
            Console.WriteLine("BookAbpModule.PostConfigureServices");
        }

        override public void ConfigureServices(ServiceConfigurationContext context)
        {
            Console.WriteLine("BookAbpModule.ConfigureServices");

            ConfigureSwaggerServices(context.Services);
        }


        override public void OnApplicationInitialization(ApplicationInitializationContext context)
        {

            Console.WriteLine("BookAbpModule.OnApplicationInitialization");

            var app = context.GetApplicationBuilder();
            var env = context.GetEnvironment();

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

            app.UseStaticFiles();
            app.UseRouting();

            app.UseSwagger();
            app.UseAbpSwaggerUI(options =>
            {
                options.SwaggerEndpoint("/swagger/v1/swagger.json", "BookApp API");
            });
            app.UseConfiguredEndpoints();
        }

        public override void OnPreApplicationInitialization(ApplicationInitializationContext context)
        {
            Console.WriteLine("BookAbpModule.OnPreApplicationInitialization");
        }
        override public void OnPostApplicationInitialization(ApplicationInitializationContext context)
        {
            Console.WriteLine("BookAbpModule.OnPostApplicationInitialization");
        }

        private void ConfigureSwaggerServices(IServiceCollection services)
        {
            services.AddAbpSwaggerGen(
                options =>
                {
                    options.SwaggerDoc("v1", new OpenApiInfo { Title = "BookApp API", Version = "v1" });
                    options.DocInclusionPredicate((docName, description) => true);
                    options.CustomSchemaIds(type => type.FullName);
                }
            );
        }
    }
}

运行结果

我们会发现,系统加载所有继承AbpModule的文件,并按序运行里面的方法实现对模块的配置

访问数据库

新建Entities文件夹并创建Book.cs

using Volo.Abp.Domain.Entities;

namespace BookApp.Entities
{
    public class Book : Entity<Guid>
    {
        public string Name { get; set; }
    }
}

添加Data目录并添加BookAbpDbContext.cs

using BookApp.Entities;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Reflection.Emit;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;

namespace BookApp.Data
{
    [ConnectionStringName("Default")]
    public class BookAbpDbContext : AbpDbContext<BookAbpDbContext>
    {
        public BookAbpDbContext(DbContextOptions<BookAbpDbContext> options)
        : base(options)
        { }

        public DbSet<Book> Books { get; set; }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.Entity<Book>(b =>
            {
                b.ToTable(nameof(Books));
            });
        }
    }
}

修改BookAbpModule.cs


using Microsoft.OpenApi.Models;
using Volo.Abp;
using Volo.Abp.Application;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Autofac;
using Volo.Abp.Domain;
using Volo.Abp.Modularity;
using Volo.Abp.Swashbuckle;
using AbpModuleA;
using AbpModuleB;
using Volo.Abp.EntityFrameworkCore;
using BookApp.Data;
using Volo.Abp.EntityFrameworkCore.Sqlite;

namespace BookApp
{
    [DependsOn(
        typeof(AbpAutofacModule),
        typeof(AbpAspNetCoreMvcModule),
        typeof(AbpSwashbuckleModule),
        typeof(AbpDddApplicationModule),
        typeof(AbpDddDomainModule),
        typeof(AbpEntityFrameworkCoreSqliteModule),
        typeof(AbpModuleAModule),
        typeof(AbpModuleBModule)

    )]
    public class BookAbpModule : AbpModule
    {
        public override void PreConfigureServices(ServiceConfigurationContext context)
        {
            Console.WriteLine("BookAbpModule.PreConfigureServices ");
        }

        override public void PostConfigureServices(ServiceConfigurationContext context)
        {
            Console.WriteLine("BookAbpModule.PostConfigureServices");
        }

        override public void ConfigureServices(ServiceConfigurationContext context)
        {
            Console.WriteLine("BookAbpModule.ConfigureServices");

            ConfigureSwaggerServices(context.Services);

            // 使用sqlite作为数据库
            context.Services.AddAbpDbContext<BookAbpDbContext>(options =>
            {
                options.AddDefaultRepositories(includeAllEntities: true);
            });

            Configure<AbpDbContextOptions>(options =>
            {
                options.UseSqlite();
            });
        }


        override public void OnApplicationInitialization(ApplicationInitializationContext context)
        {

            Console.WriteLine("BookAbpModule.OnApplicationInitialization");

            var app = context.GetApplicationBuilder();
            var env = context.GetEnvironment();

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

            app.UseStaticFiles();
            app.UseRouting();

            app.UseSwagger();
            app.UseAbpSwaggerUI(options =>
            {
                options.SwaggerEndpoint("/swagger/v1/swagger.json", "BookApp API");
            });

            app.UseConfiguredEndpoints();
        }

        public override void OnPreApplicationInitialization(ApplicationInitializationContext context)
        {
            Console.WriteLine("BookAbpModule.OnPreApplicationInitialization");
        }
        override public void OnPostApplicationInitialization(ApplicationInitializationContext context)
        {
            Console.WriteLine("BookAbpModule.OnPostApplicationInitialization");
        }

        private void ConfigureSwaggerServices(IServiceCollection services)
        {
            services.AddAbpSwaggerGen(
                options =>
                {
                    options.SwaggerDoc("v1", new OpenApiInfo { Title = "BookApp API", Version = "v1" });
                    options.DocInclusionPredicate((docName, description) => true);
                    options.CustomSchemaIds(type => type.FullName);
                }
            );
        }
    }
}

修改appsettings.json

{
   
  "ConnectionStrings": {
   
    "Default": "Data Source=BookApp.db"
  },
  "Logging": {
   
    "LogLevel": {
   
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

安装Nuget包"Microsoft.EntityFrameworkCore.Tools",并在在项目根目录下打开命令行工具,依次执行以下命令进行数据迁移和数据库更新:

dotnet ef migrations add InitialCreate
dotnet ef database update

新建Application目录

新建IBookAppService.cs

namespace BookApp.Application
{
    using BookApp.Entities;

    public interface IBookAppService
    {
        Task<string> CreateAsync(string name);
        Task<List<Book>> GetListAsync();
    }
}

新建BookAppService.cs

using BookApp.Entities;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace BookApp.Application
{
    public class BookAppService : ApplicationService, IBookAppService
    {
        public IRepository<Book, Guid> Repository => LazyServiceProvider.LazyGetRequiredService<IRepository<Book, Guid>>();

        public async Task<string> CreateAsync(string name)
        {
            var book = await Repository.InsertAsync(new Book()
            {
                Name = name
            });

            return book.Name;
        }

        public async Task<List<Book>> GetListAsync()
        {
            var list = await Repository.GetListAsync();
            return list;
        }

    }
}

在Controllers目录新建BookController.cs

using BookApp.Application;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc;
using BookApp.Entities;

namespace BookApp.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class BookController : AbpController
    {
        private readonly IBookAppService _service;

        public BookController(IBookAppService service)
        {
            _service = service;
        }

        [HttpGet]
        public Task<string> CreateAsync(string name)
        {
            return _service.CreateAsync(name);
        }

        [HttpGet("list")]
        public Task<List<Book>> GetListAsync()
        {
            return _service.GetListAsync();
        }
    }
}

整个文件结构与包引用情况如下

运行结果如下

我们可以通过这两个接口添加与显示Book信息。

参考文章

作者:吴晓阳(手机:13736969112微信同号)

目录
相关文章
|
网络协议 应用服务中间件 测试技术
Yarp 与 Nginx性能大比拼不出所料它胜利了!
Yarp 与 Nginx性能大比拼不出所料它胜利了!
417 0
|
JavaScript 前端开发 小程序
js将数组中相同的元素进行分组 必看
js将数组中相同的元素进行分组 必看
249 1
Mgo
|
存储 SQL Kubernetes
可观测性革命 - 揭秘OpenObserve开源高性能云原生平台
本文分析OpenObserve 以及其在可观测性方面如何帮助您构建更好的软件并节省观测成本
Mgo
2475 0
|
消息中间件 运维 算法
Kafka 为什么要抛弃 Zookeeper?
本文探讨了Kafka为何逐步淘汰ZooKeeper。长久以来,ZooKeeper作为Kafka的核心组件,负责集群管理和协调任务。然而,随着Kafka的发展,ZooKeeper带来的复杂性增加、性能瓶颈及一致性问题日益凸显。为解决这些问题,Kafka引入了KRaft,这是一种基于Raft算法的内置元数据管理方案,不仅简化了部署流程,还提升了系统的一致性和扩展性。本文详细分析了这一转变背后的原因及其带来的优势,并展望了Kafka未来的发展方向。
962 1
|
人工智能 缓存 监控
终于有人说清楚AI开发的全流程了!
本文详述了AI需求开发流程各阶段的关键步骤和最佳实践,包括需求调研、模型选型、提示词优化、性能测试以及上线后的监控和反馈,旨在帮助开发者构建高效、可靠的AI应用。
|
JavaScript
可自由配置的jQuery消息提示框插件toast
jquery.toast.js是一款可自由配置的jQuery消息提示框插件。该消息提示框可以自定义背景和前景色,提示框的位置,提示框的显示时间,提示框的动画效果等。
485 2
|
Rust API 开发者
【一起学Rust | 框架篇 | ws-rs框架】属于Rust的Websocket框架——ws-rs
【一起学Rust | 框架篇 | ws-rs框架】属于Rust的Websocket框架——ws-rs
1748 0
|
存储 开发框架 前端开发
Abp源码分析之虚拟文件系统Volo.Abp.VirtualFileSystem
`Volo.Abp.VirtualFileSystem` 是 ABP 框架中的一个重要组件,提供了一种抽象文件系统的方式,使应用程序可以轻松访问和管理文件资源。本文介绍了如何在 MVC 项目中使用 `Volo.Abp.VirtualFileSystem`,包括新建项目、配置模块、添加资源文件以及读取资源文件的具体步骤。通过统一的接口处理文件和目录,无论实际存储位置如何,应用程序都能更加灵活地切换不同的文件存储方式。
292 0
Abp源码分析之虚拟文件系统Volo.Abp.VirtualFileSystem
|
缓存 测试技术 C#
使用Radzen Blazor组件库开发的基于ABP框架炫酷UI主题
【10月更文挑战第20天】本文介绍了使用 Radzen Blazor 组件库开发基于 ABP 框架的炫酷 UI 主题的步骤。从准备工作、引入组件库、设计主题、集成到 ABP 框架,再到优化和调试,详细讲解了每个环节的关键点和注意事项。通过这些步骤,你可以打造出高性能、高颜值的应用程序界面。
568 1

热门文章

最新文章