在开展架构的型号选择时,常常会听见“***架构过重了”这类的响声,例如“Abp过重了,不宜大家...”。实际上,Abp架构确实非常重吗?

架构的“轻”和“重”,也没有在网络上寻找确立的界定,根据阅读文章一些个人博客,大概能够 把架构的“轻”和“重”根据下列好多个层面开展区别:

  • 所依靠程序流程集的总数

  • 所完成的作用的是多少

  • 入门难度系数及便捷性

“轻量”的架构,大约指的是一个程序流程集依靠少且程序流程集文档小、作用虽少但充足满足需求、入门非常容易应用简易的架构;“超重量级”的架构,大约指的是一个程序流程集依靠多且程序流程集文档大、功能丰富但大部分用不上、入门艰难且应用艰难的架构。

本文将从以上好多个层面来探寻Abp是一个“轻量”或是“超重量级”的架构。

最少依靠

Abp开发设计了一些运行模版来为大家转化成新项目。运行模版选用了领域驱动设计方案的分层次计划方案来创建新项目等级,包含了展现层网络层行业层基础设施建设层

Architecture

大家一般 都是会根据Abp CLI或Abp.io来建立相近图中构架的新项目。Abp为大家转化成的新项目,降低了大家复位新项目的劳动量,拆箱即用,因而将大家很有可能会应用的Nuget包事先引进到大家的新项目中,也就给大家一种依靠项过多的觉得。

Dependency

从架构模式上而言,模块化设计是Abp的关键;而从技术性视角看来,依赖注入则是Abp完成诸多作用的一个关键方式。只需掌握Abp的模块化设计依赖注入,大家就可以根据Abp架构来开展新项目开发设计。

下面将建立一个原生态的ASP.NET Core Web API新项目,紧紧围绕模块化设计依赖注入两个核心定义,来展现怎样以最少依靠的方法应用Abp。

  • 根据VS或是dotNet cli新创建一个原生态的ASP.NET Core Web API新项目,取名为LightweightAbp

  • 安裝Nuget包Volo.Abp.AutofacVolo.Abp.AspNetCore.Mvc

  • 将新项目开展模块化设计:在新项目网站根目录新创建一个Abp控制模块编码文档LightweightAbpModule.cs,并拷贝下列编码:

[DependsOn(
    typeof(AbpAutofacModule),
    typeof(AbpAspNetCoreMvcModule))]
public class LightweightAbpModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
    }

    public override void OnApplicationInitialization(ApplicationInitializationContext context)
    {
    }
}
  • Startup中的编码调节到LightweightAbpModule中,编码以下:

[DependsOn(
    typeof(AbpAutofacModule),
    typeof(AbpAspNetCoreMvcModule))]
public class LightweightAbpModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        context.Services.AddControllers();
        context.Services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "LightweightAbp", Version = "v1" });
        });
    }

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

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseSwagger();
            app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "LightweightAbp v1"));
        }

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
}
  • 变更Startup中的编码以应用Abp的模块化设计系统软件:

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

    public void Configure(iapplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
    {
        app.InitializeApplication();
    }
}
  • 变更ProgramCreateHostBuilder方式以应用Abp的依赖注入系统软件(根据Autofac):

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {         webBuilder.UseStartup<Startup>();
                })
                .UseAutofac();
  • 将新项目转化成的WeatherForecastController基类ControllerBase更改成AbpController

  • F5运作。

到此新项目的建立完成了。能够 见到,只是依靠了Volo.Abp.AutofacVolo.Abp.AspNetCore.Mvc2个Nuget包,就可以运用Abp开展开发设计。若从所依靠Nuget包总数来评定架构的“轻”和“重”,那麼Abp不可谓不轻。

作用按需应用

归功于模块化设计设计方案,Abp将其所能给予的作用,区划并封裝到不一样的控制模块中。要想应用Abp给予的某一作用,只需引进有关的Nuget包并依靠(DependsOn)控制模块就可以。

数据信息浏览

要想完成数据信息浏览作用,最先大家必须 界定EntityDbContext并配备数据库查询适用。在Abp的层级构架中,EntityRepository归属于行业层,Service归属于网络层,DbContext则归属于EntityFramework Core控制模块,因而大家按需引进所需控制模块就可以。

  • 安裝Nuget包Volo.Abp.Ddd.ApplicationVolo.Abp.Ddd.DomainVolo.Abp.EntityFrameworkCore.Sqlite

  • LightweightAbpModule类中配备DependsOn特点,将AbpDddApplicationModuleAbpDddDomainModuleAbpEntityFrameworkCoreSqliteModule控制模块依靠到大家的新项目控制模块中。

    [DependsOn(
        typeof(AbpAutofacModule),
        typeof(AbpAspNetCoreMvcModule),
        typeof(AbpDddApplicationModule),
        typeof(AbpDddDomainModule),
        typeof(AbpEntityFrameworkCoreSqliteModule))]
    public class LightweightAbpModule : AbpModule
    { ... }
  • 随后建立实体线Book及数据库查询前后文LightweightAbpDbContext:

using System;
using Volo.Abp.Domain.Entities;

namespace LightweightAbp
{
    public class Book : Entity<Guid>
    {
        public string Name { get; set; }
    }
}
[ConnectionStringName("Default")]
public class LightweightAbpDbContext : AbpDbContext<LightweightAbpDbContext>
{
    public LightweightAbpDbContext(DbContextOptions<LightweightAbpDbContext> 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));
        });
    }
}
  • LightweightAbpModuleConfigureServices方式中配备数据库查询浏览:

public override void ConfigureServices(ServiceConfigurationContext context)
{
    ...

    context.Services.AddAbpDbContext<LightweightAbpDbContext>(options =>
    {
        options.AddDefaultRepositories(includeAllEntities: true);
    });

    Configure<AbpDbContextOptions>(options =>
    {
        options.UseSqlite();
    });
}
  • appsettings.json中配备连接数据库字符串数组

{
  ...
  "ConnectionStrings": {
    "Default": "Data Source=LightweightAbp.db"
  }
}
  • 安裝Nuget包"Microsoft.EntityFrameworkCore.Tools",并在在新项目根目录下开启命令行工具,先后实行下列指令开展数据备份转移和数据库查询升级:

dotnet ef migrations add InitialCreate
dotnet ef database update
  • 建立IBookAppServiceBookAppService:

public interface IBookAppService
{
    Task CreateAsync(string name);
}
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;
    }
}
  • 在文件夹名称Controllers中建立BookController:

[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);
    }
}
  • F5以开发者模式运作就可以在Swagger网页页面上插进数据信息:

CreateBook

这儿大家完成了简易的数据信息插进。能够 见到,新项目中并沒有应用繁杂构架和繁杂的领域驱动设计方案,仅引入并配备Abp控制模块,就可以应用基本的 ASP.NET Core Web API方法开展开发设计。

缓存文件

下面大家将再次完成缓存文件作用。

  • 引入Nuget包Volo.Abp.Caching并向LightweightAbpModule加上AbpCachingModule控制模块依靠;

  • 改动IBookAppServiceBookAppService完成GetAllAsync方式:

public interface IBookAppService
{
    Task<string> CreateAsync(string name);

    Task<string[]> GetAllAsync();
}
public class BookAppService : ApplicationService, IBookAppService
{
    private readonly IRepository<Book, Guid> _repository;
    private readonly IDistributedCache<string[]> _cache;

    public BookAppService(
        IRepository<Book, Guid> repository,
        IDistributedCache<string[]> cache)
    {
        _repository = repository;
        _cache = cache;
    }

    public async Task<string> CreateAsync(string name)
    { ... }

    public async Task<string[]> GetAllAsync()
    {
        return await _cache.GetOrAddAsync(
            "AllBooksName",
            async () => await _repository.Select(b => b.Name).ToArrayAsync(),
            () => new DistributedCacheEntryOptions
            {
                AbsoluteExpiration = DateTimeOffset.Now.AddHours(1)
            }
        );
    }
}
  • 改动BookAppService完成GetAllAsyncAPI插口:

public class BookController : AbpController
{
    ...

    [HttpGet("all")]
    public Task<string[]> GetAllAsync()
    {
        return _service.GetAllAsync();
    }
}
  • F5以调节方法运作,就可以启用完成了缓存文件作用的GetAllAsync插口。

这儿大家完成了缓存文件作用。不言而喻,按需应用缓存文件作用所属的Nuget包及控制模块就可以,并沒有许多复杂的实际操作。

大家都知道,Abp完成了非常多的作用,在其中有一些作用或许全部新项目生命期上都不容易采用。归功于模块化设计的方法,我们可以只依靠我所必须 的Nuget包和Abp控制模块。假如依据作用是多少来评定架构的“轻”和“重”,大家按需依靠不一样控制模块时Abp架构不可谓不轻。不难看出,一个架构的“轻”和“重”,有时候还会继续在于应用方法。

入门难度系数及便捷性

学习培训一门新技术应用最好是的起始点就是官方网文本文档,Abp也是这般,Abp的官方网文本文档十分详细详细介绍了每个作用。Abp更为大家给予了运行模版,模版遵照了领域驱动设计方案的最佳实践来开展新项目分层次,而且为大家承继了许多新项目中常见的程序模块。

针对新手来讲,应对一个繁杂的分层次构架及丰富多彩的作用特点适用,一瞬间必须 接纳十分多的专业知识,因而会造成找不到方向的觉得,从而得到一种入门难度系数高,架构很“重”的结果。

假如从此外一种视角来学习培训Abp得话,或许状况会各有不同。在文中之初,我便明确提出了Abp的关键是模块化设计依赖注入的见解,在我们将新手入门的关键放到模块化设计依赖注入上,那麼会发觉Abp是一个非常容易入门而且学习曲线很轻缓的架构。如同上文我所开展的编码演试,假如觉得这一演试新项目简单易学,那麼就证实了我这一见解。

对于便捷性,最先Abp完成的作用很全方位,我们可以按需应用;次之,伴随着对Abp架构的逐渐深层次,会发觉模块化设计的设计方案使我们的新项目集成化多种多样作用越来越简易,而且伴随着新项目的演变,Abp的模块化设计给大家给予了随便转换到微项目实施方案的工作能力;依赖注入系统软件使我们可以随便的订制并更换Abp默认设置完成的作用。因而,我觉得Abp是一个便于应用的架构。

汇总

在这儿大家从一个不一样的视角来了解了Abp架构,不言而喻,针对Abp而言,是不是太“重”,和大家对他的认知能力及应用方法有非常大的关系。

新项目实例编码将代管在GitHub中。

感谢

谢谢Abp群(QQ群:48039003)的群员们给予的热情协助。

评论(0条)

刀客源码 游客评论