Abp原始碼分析之Abp最小系統

shiningrise發表於2024-11-02

最小系統

建立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資訊。

參考文章

  • Abp太重了?輕量化Abp框架

作者:吳曉陽(手機:13736969112微信同號)

相關文章