使用ABP框架中踩過的坑系列2
ABP中有很多慣例,如果使用得當,可以事半功倍,如果使用不當,也會有很大的麻煩,是否適當其實還是要看Need需求
ASP.NET Boilerplate (ABP) is an
open source and well documented application framework
started idea of "developing a
common
framework for all companies and all developers!" It's not just a framework but also provides a strong
architectural model
based on
Domain Driven Design
and
best practices
in mind. 開源和文件友好,適合所有公司所有開發者的公共框架,基於DDD提供強壯架構,並且是最佳實踐,這是作者的預期目標。
看一下,程式碼例子,也許是程式設計師更喜歡的方式:
public class TaskAppService : ApplicationService, ITaskAppService
{
private readonly IRepository<Task> _taskRepository;
public TaskAppService(IRepository<Task> taskRepository)
{
_taskRepository = taskRepository;
}
[AbpAuthorize(MyPermissions.UpdatingTasks)]
public async Task UpdateTask(UpdateTaskInput input)
{
Logger.Info("Updating a task for input: " + input);
var task = await _taskRepository.FirstOrDefaultAsync(input.TaskId);
if (task == null)
{
throw new UserFriendlyException(L("CouldNotFoundTheTaskMessage"));
}
input.MapTo(task);
}
}
Here, we see a sample
Application Service
method. An application service, in DDD, is directly used by presentation layer to perform
use cases
of the application. We can think that
UpdateTask method is called by javascript via AJAX. Let's see ABP's some benefits here:
Application Service
的方法,在DDD中對應的是UseCase用例,用例是什麼?是使用者需求,不清楚的同學請參考《有效需求分析》一書。從B/S角度看,該方法是由頁面中js的AJAX呼叫的(其實也可能是被手機端APP呼叫的)。這個方式帶來以下好處(注意要使用得當才有的,否則適得其反)
- Dependency Injection : ABP uses and provides a strong and conventional DI infrastructure. Since this class is an application service, it's conventionally registered to DI container as transient (created per request). It can simply inject all dependencies (as IRepository<Task> in this sample).
依賴注入,的確是個最佳實踐,如果不用依賴注入,你的程式碼中可能由50%以上要考慮:如何例項化依賴(被呼叫方),但帶來方便的同時,可能增加了閱讀程式碼的難度,因為你看到的都是介面,實現都隱藏起來,找起來比較費勁。比如這裡ApplicationService依賴的IRepository<Task>, 想真正瞭解它的程式碼,是間比較困難的。ABP中大量使用的依賴方式是,
也就是慣例依賴,這個對剛開始接觸ABP的開發者來講,是需要好好理解,才能好好利用IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
以上說明,實現ITransientDependency、 ISingletonDependency 、IInterceptor 這三個介面的類會被自動Register,當然也就可以Resolve注入; 其實IOC就是和一個全域性的容器,可以把它看作一個巨大的一個全域性變數,就時Register和Resolve 兩個步驟,你存了銀行,自然也能取錢了,就這麼簡單。public class BasicConventionalRegistrar : IConventionalDependencyRegistrar { public void RegisterAssembly(IConventionalRegistrationContext context) { //Transient context.IocManager.IocContainer.Register( Classes.FromAssembly(context.Assembly) .IncludeNonPublicTypes() .BasedOn<ITransientDependency>() .WithService.Self() .WithService.DefaultInterfaces() .LifestyleTransient() ); //Singleton context.IocManager.IocContainer.Register( Classes.FromAssembly(context.Assembly) .IncludeNonPublicTypes() .BasedOn<ISingletonDependency>() .WithService.Self() .WithService.DefaultInterfaces() .LifestyleSingleton() ); //Windsor Interceptors context.IocManager.IocContainer.Register( Classes.FromAssembly(context.Assembly) .IncludeNonPublicTypes() .BasedOn<IInterceptor>() .WithService.Self() .LifestyleTransient() ); } }
- Repository : ABP can create a default repository for each entity (as IRepository<Task> in this example). Default repository has many useful methods as FirstOrDefault used in this example. We can easily extend default repository upon our needs. Repositories abstracts DBMS and ORMs and simplifies data access logic.
Repository 實際上是ABP架構程式碼量比較大的一部分,它抽象了DBMS和ORMS, 其實和UnitOfWork也有關聯,在實際專案的CRUD方面提供了幾乎所有的幾十個方法,遺憾的是沒有提供資料庫的批量插入、批量更新, 我自己做了個擴充,到時做成nuget庫分享給大家 - Authorization : ABP can check permissions. It prevents access to UpdateTask method if current user has no "updating task" permission or not logged in. It simplifies authorization using declarative attributes but also has additional ways of authorization.
使用者和角色管理,專案中的基本模組,原來Microsoft有個MemberShip, 現在用Identity,ABP這塊整合的比較好,可以真正實現宣告式程式設計 - Validation : ABP automatically checks if input is null. It also validates all properties of an input based on standard data annotation attributes and custom validation rules. If request is not valid, it throws a proper validation exception.
宣告式驗證,加上少量程式碼,基本上可以滿足Need, 關鍵是直接用於DTO,而且有UI的配套,這塊效率可以大大提高
相關文章
- ABP框架踩坑記錄框架
- JasperReport 中踩過的坑
- vue-element-admin 使用過程中踩坑Vue
- GeoServer 踩過的坑Server
- vue專案中踩過的element的坑Vue
- IDEA建立Maven專案中踩過的坑IdeaMaven
- 記錄自己在tensorflow中踩過的坑
- ?踩坑指南——onnx系列
- 前端踩坑系列《四》前端
- 你踩過flutter的坑嗎Flutter
- 解析資料踩過的坑
- electron踩坑系列之一
- vue系列之踩坑之旅Vue
- 小程式踩坑(2)
- 親自踩過的vue的坑Vue
- URLEncoder使用踩坑
- MQTT使用踩坑MQQT
- 面試中的這些坑,你踩過幾個?面試
- (踩坑)WSL2+docker+laradock 配置並安裝 Laravel 框架DockerLaravel框架
- Compose 延遲列表踩過的坑
- 安裝 Laravel/horizon 踩過的坑Laravel
- uniapp之那些年踩過的坑APP
- wepy小程式踩過的坑(1)
- html2canvas的踩坑之路HTMLCanvas
- Electron踩坑日記-2
- 關於最近開發小程式中踩過的那些坑
- 又踩坑了!BigDecimal使用的5個坑!Decimal
- [踩坑] Go Modules 使用Go
- SpringBootAdmin-使用踩坑Spring Boot
- 通過PAML中的CODEML模組計算dnds的過程以及踩坑
- 踩過的坑(一)——web容器升級Web
- linux環境壓測踩過的坑Linux
- Redis 叢集部署及踩過的坑Redis
- 使用 Markdown 寫技術部落格,我踩過的 6個坑
- HTML5中Audio使用踩坑彙總HTML
- Node系列-爬蟲踩坑筆記爬蟲筆記
- 我在秋招中踩過的那些坑|掘金技術徵文
- WSL2和CUDA踩坑