Abp太重了?轻量化Abp框架

本文首发于个人博客(https://blog.zhangchi.fun/)

在进行框架的选型时,经常会听到“***框架太重了”之类的声音,比如“Abp太重了,不适合我们...”。事实上,Abp框架真的很重吗?

框架的“轻”和“重”,我没有在网上找到明确的定义,通过阅读一些技术博客,大致可以把框架的“轻”和“重”通过以下几个方面进行区分:

  • 所依赖程序集的数量

  • 所实现的功能的多少

  • 上手难度及易用性

“轻量级”的框架,大概指的是一个程序集依赖少且程序集文件小、功能虽少但足够满足需求、上手容易使用简单的框架;“重量级”的框架,大概指的是一个程序集依赖多且程序集文件大、功能丰富但大多数用不到、上手困难且使用困难的框架。

这篇文章将从上述几个方面来探索Abp是一个“轻量级”还是“重量级”的框架。

最小依赖

Abp开发了一些启动模板来为我们生成项目。启动模板采用了领域驱动设计的分层方案来建立项目层级,包括了展示层应用层领域层基础设施层

我们通常都会通过Abp CLI或Abp.io来创建类似上图架构的项目。Abp为我们生成的项目,减少了我们初始化项目的工作量,开箱即用,因此将我们可能会使用的Nuget包预先引入到我们的项目中,也就给我们一种依赖项太多的感觉。

从架构设计上来讲,模块化是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.Mvc两个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页面上插入数据:

这里我们实现了简单的数据插入。可以看到,项目中并没有使用复杂架构和复杂的领域驱动设计,仅引用并配置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)的群友们提供的热心帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/300357.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

六月赞歌

七月的脚步离我们近了&#xff0c;在六月即将过去的时候我是有些话想说的。今年的6月过得很充实&#xff0c;虽谈不上硕果累累&#xff0c;但至于还是收获颇丰。在这最想提的是生活杂谈小组在几位组长们的激情带动&#xff0c;各组员的热情参与下&#xff0c;站到了小组排行榜的…

避不开的分布式事务

前言关于前面系列的文章已经说到分布式服务之间的通信&#xff0c;则分布式事务接下来就是我们要一起学习的主题&#xff0c;走起。数据库事务在现有大大小小的系统中几乎是避免不开的&#xff0c;或多或少总会有一些业务关联在一块&#xff1b;对于单机事务的应用场景和操作&a…

matlab如何求矩阵的转置矩阵,怎么用MATLAB程序求转置矩阵?急需,高手帮忙………………...

在Matlab下输入&#xff1a;edit&#xff0c;然后将下面两行百分号之间的内容&#xff0c;复制进去&#xff0c;保存%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function ff31(x)f1./[(x-2).^20.1]1./[(x-3).^40.01];%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 返…

任正非一语中的,未来科技的发展核心靠他们!

▲ 点击查看今年6月&#xff0c;华为的任正非接受媒体的采访&#xff0c;多次谈及基础教育&#xff0c;不禁流下了英雄泪&#xff0c;谈话中&#xff0c;曾27次提到了数学&#xff0c;并且表示等自己退休后要找一个好大学&#xff0c;好好地学一学数学。他还谈到了数学对于华…

Windows 2003下×××服务器架设攻略

原文地址[url]http://bbs.51cto.com/thread-49347-1-1.html[/url]Windows 2003下服务器架设攻略笔者有不少朋友因为工作关系常常移动办公&#xff0c;因此资料的传递、与公司信息的及时交流或是累了想在异地打开公司或家里的电脑看看电影等等应用显得很头疼。这方面的应用也就是…

微软出手,蚕食JetBrains系市场?

文 | Travis出品 | OSC开源社区&#xff08;ID&#xff1a;oschina2013&#xff09;近日微软公布了针对 Java 编程语言的 Visual Studio Code 更新路线图&#xff0c;根据路线图的计划&#xff0c;微软将在开发体验、安全、远程开发等方面做出改善。这个更新路线图涵盖了 2021 …

matlab dy,高手,请问用matlab如何解下面方程:y*Dy=a+b*y;我的计算结果里面含有wrightOmega ,怎样解出一般解?...

满意答案weiliyao772013.07.20采纳率&#xff1a;49% 等级&#xff1a;12已帮助&#xff1a;11659人#include #include using namespace std;#define N 20double a[N][N];double x[N1];double b[N1];int n;//n方程个数&#xff0c;n未知数个数int set( ){cout<cin>>…

[005] .NET 的执行模型

.NET大牛之路 • 王亮精致码农 • 2021.07.06前面我们介绍 .NET 历史时讲过&#xff0c;微软基于 .NET Framework 重新设计并创造了跨平台的 .NET Core&#xff0c;目前已经发展到 .NET 5 版本&#xff0c;它的性能较之前的 .NET Framework 有巨大的提升。而 .NET Framework 产…

美国警察开特斯拉追疑犯,时速飙到193公里,然后发现没电了...

全世界只有3.14 % 的人关注了青少年数学之旅晚上11点&#xff0c;时速一度高达193公里&#xff01;美国警察在湾区的一条州际公路上&#xff0c;对嫌犯实施追捕。与往常不同的是&#xff0c;这位警员驾驶的是一辆特斯拉Model S&#xff0c;0到60英里&#xff08;96公里&#xf…

Hello Blazor:(6)你必须踩过这5个坑,才算学会部署Blazor WebAssembly到静态网站

上次的文章中&#xff0c;我们介绍了Blazor WebAssembly可以部署到静态文件服务器&#xff0c;而每个Github账户都可以使用GitHub Pages功能开一个自己的静态网站。那么&#xff0c;不用花钱购买服务器&#xff0c;就可以将Blazor WebAssembly项目部署到GitHub Pages作为demo展…

做题不如巧做题,初中数学题型解题技巧都在这!

▲ 点击查看今天&#xff0c;小天就为大家整理了初中数学各类题型解题技巧。我们一起往下看哦。1.数形结合思想根据数学问题的条件和结论之间的内在联系&#xff0c;既分析其代数含义&#xff0c;又揭示其几何意义&#xff1b;使数量关系和图形巧妙和谐地结合起来&#xff0c…

【Blog.Core开源】快速升级.NET 6.0

BCVP只要贡献&#xff0c;就不分大小&#xff0c;每个人都是这个时代最璀璨的星&#xff01;一个以开源项目主导的社区组织。《Blog.Core》开源项目已经3年&#xff0c;期间收获了很多很多&#xff0c;同时也收到了很多小伙伴的支持和鼓励&#xff0c;才使得我有足够的心力从2.…

eclipse默认编码为GBK,修改为UTF8的方法

2019独角兽企业重金招聘Python工程师标准>>> eclipse 默认编码居然是GBK&#xff0c;js文件默认编码是ISO-....怎么可以这样呢&#xff1f;都修改成UTF8的方法&#xff1a;1、windows->Preferences...打开"首选项"对话框&#xff0c;左侧导航树&#x…

php中页面平滑回到顶部代码,原生JS实现平滑回到顶部组件_javascript技巧

返回顶部组件是一种极其常见的网页功能&#xff0c;需求简单&#xff1a;页面滚动一定距离后&#xff0c;显示返回顶部的按钮&#xff0c;点击该按钮可以将滚动条滚回至页面开始的位置。实现思路也很容易&#xff0c;只要改变document.documentElement.scrollTop或document.bod…

数学有多震撼?!我真的没有在开车!

让我们来欣赏一下日本高校欧派函数&#xff08;おっぱい関数&#xff09;对抗大赛中的作品吧。埼玉大学&#xff08;理学部&#xff09;其中 明治大学広島大学&#xff08;理学部&#xff09;東京農業大学其中 是一个可调常数&#xff0c;下图中p3。文教大学京都大学其中首都大…

一些微服务拆分的浅见

大家好&#xff0c;我是Z哥。不管是十几年前 SOA 的流行&#xff0c;还是 7、8 年前微服务的大行其道&#xff0c;还是如今云原生的展露锋芒&#xff0c;背后都离不开一件事&#xff0c;程序拆分或者说服务拆分。否则&#xff0c;一个单体应用&#xff0c;以上的这些技术潮流好…

大变天!刚刚,山东突然宣布!关乎800万人...

全世界只有3.14 % 的人关注了青少年数学之旅由山东省大数据局主办、青岛市大数据发展管理局承办的山东省数据应用&#xff08;青岛&#xff09;创新创业大赛自9月23日启动以来&#xff0c;凭借着新颖赛题、丰富数据和丰厚奖励&#xff0c;吸引了社会各界数据爱好者与从业者的广…

MassTransit中RequestResponse基本使用

MassTransit 是一个自由、开源、轻量级的消息总线基于.Net框架, 用于创建分布式应用程序。方便搭建基于消息的松耦合异步通信的应用程序和服务。MassTransit 在现有消息传输上提供了一组广泛的功能, 从而使开发人员能够友好地使用基于消息的会话模式异步连接服务。基于消息的通…

php2612,达人曝光LGLSNJ2612AR质量好吗?怎么样呢?体验报告揭秘

其实这个LGLSNJ2612AR还可以的 哟&#xff0c;超凡的造型设计和外观&#xff0c;做工细腻&#xff0c;不少的人想要了解这LGLSNJ2612AR怎么样&#xff1f;质量好不好&#xff1f;实实在在的说这款LGLSNJ2612AR使用体验后个人感觉蛮可以的哈&#xff0c;刚购没多久的&#xff0c…

vim编辑技巧

转载于:https://blog.51cto.com/ovcer/1353415