Abp源码分析之Abp最小系统

最小系统

创建API项目

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

修改Program.cs为以下内容

C# 复制代码
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

C# 复制代码
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

C# 复制代码
//加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

C# 复制代码
//加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项目的模块配置文件

C# 复制代码
//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

C# 复制代码
using Volo.Abp.Domain.Entities;

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

添加Data目录并添加BookAbpDbContext.cs

C# 复制代码
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

C# 复制代码
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

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

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

c# 复制代码
dotnet ef migrations add InitialCreate
dotnet ef database update

新建Application目录

新建IBookAppService.cs

C# 复制代码
namespace BookApp.Application
{
    using BookApp.Entities;

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

新建BookAppService.cs

C# 复制代码
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

C# 复制代码
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微信同号)