@
我們將封裝通用的應用層,介面以及控制器基礎類別。
建立介面ICurdAppService,在這裡我們定義了通用的增刪改查介面。
其中的泛型引數:
public interface ICurdAppService<TGetOutputDto, TGetListOutputDto, in TKey, in TGetListInput, in TCreateInput, in TUpdateInput>
{
Task<TGetOutputDto> GetAsync(TKey id);
Task<PagedResultDto<TGetListOutputDto>> GetAllAsync(TGetListInput input);
Task<TGetOutputDto> CreateAsync(TCreateInput input);
Task<TGetOutputDto> UpdateAsync(TUpdateInput input);
Task DeleteAsync(TKey id);
}
建立應用層服務CurdAppServiceBase,它是一個抽象類,繼承自Abp.Application.Services.CrudAppService。
程式碼如下:
public abstract class CurdAppServiceBase<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
: CrudAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
where TEntity : class, IEntity<TKey>
where TGetOutputDto : IEntityDto<TKey>
where TGetListOutputDto : IEntityDto<TKey>
{
protected CurdAppServiceBase(IRepository<TEntity, TKey> repository)
: base(repository)
{
}
}
建立控制器類CurdController,繼承自AbpControllerBase。並實現ICurdAppService介面。
程式碼如下:
public abstract class CurdController<ITAppService, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
: AbpControllerBase
where ITAppService : ICurdAppService<TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
where TGetOutputDto : IEntityDto<TKey>
where TGetListOutputDto : IEntityDto<TKey>
{
private readonly ITAppService _recipeAppService;
public CurdController(ITAppService recipeAppService)
{
_recipeAppService = recipeAppService;
}
[HttpPost]
[Route("Create")]
public virtual async Task<TGetOutputDto> CreateAsync(TCreateInput input)
{
return await _recipeAppService.CreateAsync(input);
}
[HttpDelete]
[Route("Delete")]
public virtual async Task DeleteAsync(TKey id)
{
await _recipeAppService.DeleteAsync(id);
}
[HttpGet]
[Route("GetAll")]
public virtual async Task<PagedResultDto<TGetListOutputDto>> GetAllAsync(TGetListInput input)
{
return await _recipeAppService.GetAllAsync(input);
}
[HttpGet]
[Route("Get")]
public virtual async Task<TGetOutputDto> GetAsync(TKey id)
{
return await _recipeAppService.GetAsync(id);
}
[HttpPut]
[Route("Update")]
public virtual async Task<TGetOutputDto> UpdateAsync(TUpdateInput input)
{
return await _recipeAppService.UpdateAsync(input);
}
}
為了相容舊版Abp,需更改增刪查改服務(CrudAppService)的方法簽名,可參考[Volo.Abp升級筆記]使用舊版Api規則替換RESTful Api以相容老程式,此處不再贅述。
將UpdateAsync,GetListAsync方法封閉:
private new Task<TGetOutputDto> UpdateAsync(TKey id, TUpdateInput input)
{
return base.UpdateAsync(id, input);
}
private new Task<PagedResultDto<TGetListOutputDto>> GetListAsync(TGetListInput input)
{
return base.GetListAsync(input);
}
封閉原有UpdateAsync, 新增的UpdateAsync方法更改了方法簽名:
public virtual async Task<TGetOutputDto> UpdateAsync(TUpdateInput input)
{
await CheckUpdatePolicyAsync();
var entity = await GetEntityByIdAsync((input as IEntityDto<TKey>).Id);
MapToEntity(input, entity);
await Repository.UpdateAsync(entity, autoSave: true);
return await MapToGetOutputDtoAsync(entity);
}
Brief是一種簡化的查詢實體集合的方法,其返回的Dto不包含導航屬性,以減少資料傳輸量。
新增GetAllAsync和GetAllBriefAsync方法:
public virtual Task<PagedResultDto<TGetListOutputDto>> GetAllAsync(TGetListInput input)
{
return this.GetListAsync(input);
}
public async Task<PagedResultDto<TGetListBriefOutputDto>> GetAllBriefAsync(TGetListBriefInput input)
{
await CheckGetListPolicyAsync();
var query = await CreateBriefFilteredQueryAsync(input);
var totalCount = await AsyncExecuter.CountAsync(query);
var entities = new List<TEntity>();
var entityDtos = new List<TGetListBriefOutputDto>();
if (totalCount > 0)
{
query = ApplySorting(query, input);
query = ApplyPaging(query, input);
entities = await AsyncExecuter.ToListAsync(query);
entityDtos = ObjectMapper.Map<List<TEntity>, List<TGetListBriefOutputDto>>(entities);
}
return new PagedResultDto<TGetListBriefOutputDto>(
totalCount,
entityDtos
);
}
目前為止,我們的應用層基礎類別繼承於Abp.Application.Services.CrudAppService
為了更好的程式碼重用,我們對泛型引數進行擴充套件,使用CurdAppServiceBase的類可根據實際業務需求選擇泛型引數
其中的泛型引數:
首先擴充套件ICurdAppService:
public interface ICurdAppService<TEntityDto, in TKey>
: ICurdAppService<TEntityDto, TKey, PagedAndSortedResultRequestDto>
{
}
public interface ICurdAppService<TEntityDto, in TKey, in TGetListInput>
: ICurdAppService<TEntityDto, TKey, TGetListInput, TEntityDto>
{
}
public interface ICurdAppService<TEntityDto, in TKey, in TGetListInput, in TCreateInput>
: ICurdAppService<TEntityDto, TKey, TGetListInput, TCreateInput, TCreateInput>
{
}
public interface ICurdAppService<TEntityDto, in TKey, in TGetListInput, in TCreateInput, in TUpdateInput>
: ICurdAppService<TEntityDto, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
{
}
public interface ICurdAppService<TGetOutputDto, TGetListOutputDto, in TKey, in TGetListInput, in TCreateInput, in TUpdateInput>
: ICurdAppService<TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TGetListInput, TCreateInput, TUpdateInput>
{
}
public interface ICurdAppService<TGetOutputDto, TGetListOutputDto, in TKey, in TGetListInput, in TGetListBriefInput, in TCreateInput, in TUpdateInput>
: ICurdAppService<TGetOutputDto, TGetListOutputDto, TGetListOutputDto, TKey, TGetListInput, TGetListBriefInput, TCreateInput, TUpdateInput>
{
}
public interface ICurdAppService<TGetOutputDto, TGetListOutputDto, TGetListBriefOutputDto, in TKey, in TGetListInput, in TGetListBriefInput, in TCreateInput, in TUpdateInput>
{
Task<TGetOutputDto> GetAsync(TKey id);
Task<PagedResultDto<TGetListOutputDto>> GetAllAsync(TGetListInput input);
Task<TGetOutputDto> CreateAsync(TCreateInput input);
Task<TGetOutputDto> UpdateAsync(TUpdateInput input);
Task DeleteAsync(TKey id);
Task<PagedResultDto<TGetListBriefOutputDto>> GetAllBriefAsync(TGetListInput input);
}
擴充套件CurdAppServiceBase:
public abstract class CurdAppServiceBase<TEntity, TEntityDto, TKey>
: CurdAppServiceBase<TEntity, TEntityDto, TKey, PagedAndSortedResultRequestDto>
where TEntity : class, IEntity<TKey>
where TEntityDto : IEntityDto<TKey>
{
protected CurdAppServiceBase(IRepository<TEntity, TKey> repository)
: base(repository)
{
}
}
public abstract class CurdAppServiceBase<TEntity, TEntityDto, TKey, TGetListInput>
: CurdAppServiceBase<TEntity, TEntityDto, TKey, TGetListInput, TEntityDto>
where TEntity : class, IEntity<TKey>
where TEntityDto : IEntityDto<TKey>
{
protected CurdAppServiceBase(IRepository<TEntity, TKey> repository)
: base(repository)
{
}
}
public abstract class CurdAppServiceBase<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput>
: CurdAppServiceBase<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput, TCreateInput>
where TEntity : class, IEntity<TKey>
where TEntityDto : IEntityDto<TKey>
{
protected CurdAppServiceBase(IRepository<TEntity, TKey> repository)
: base(repository)
{
}
}
public abstract class CurdAppServiceBase<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
: CurdAppServiceBase<TEntity, TEntityDto, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
where TEntity : class, IEntity<TKey>
where TEntityDto : IEntityDto<TKey>
{
protected CurdAppServiceBase(IRepository<TEntity, TKey> repository)
: base(repository)
{
}
protected override Task<TEntityDto> MapToGetListOutputDtoAsync(TEntity entity)
{
return MapToGetOutputDtoAsync(entity);
}
protected override TEntityDto MapToGetListOutputDto(TEntity entity)
{
return MapToGetOutputDto(entity);
}
}
public abstract class CurdAppServiceBase<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
: CurdAppServiceBase<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TGetListInput, TCreateInput, TUpdateInput>
where TEntity : class, IEntity<TKey>
where TGetOutputDto : IEntityDto<TKey>
where TGetListOutputDto : IEntityDto<TKey>
{
protected CurdAppServiceBase(IRepository<TEntity, TKey> repository)
: base(repository)
{
}
}
public abstract class CurdAppServiceBase<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
: CurdAppServiceBase<TEntity, TGetOutputDto, TGetListOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
where TEntity : class, IEntity<TKey>
where TGetOutputDto : IEntityDto<TKey>
where TGetListOutputDto : IEntityDto<TKey>
{
protected CurdAppServiceBase(IRepository<TEntity, TKey> repository)
: base(repository)
{
}
}
擴充套件CurdController
public abstract class CurdController<ITAppService, TEntityDto, TKey>
: CurdController<ITAppService, TEntityDto, TKey, PagedAndSortedResultRequestDto>
where ITAppService : ICurdAppService<TEntityDto, TKey>
where TEntityDto : IEntityDto<TKey>
{
protected CurdController(ITAppService appService)
: base(appService)
{
}
}
public abstract class CurdController<ITAppService, TEntityDto, TKey, TGetListInput>
: CurdController<ITAppService, TEntityDto, TKey, TGetListInput, TEntityDto>
where ITAppService : ICurdAppService<TEntityDto, TKey, TGetListInput>
where TEntityDto : IEntityDto<TKey>
{
protected CurdController(ITAppService appService)
: base(appService)
{
}
}
public abstract class CurdController<ITAppService, TEntityDto, TKey, TGetListInput, TCreateInput>
: CurdController<ITAppService, TEntityDto, TKey, TGetListInput, TCreateInput, TCreateInput>
where ITAppService : ICurdAppService<TEntityDto, TKey, TGetListInput, TCreateInput>
where TEntityDto : IEntityDto<TKey>
{
protected CurdController(ITAppService appService)
: base(appService)
{
}
}
public abstract class CurdController<ITAppService, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
: CurdController<ITAppService, TEntityDto, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
where ITAppService : ICurdAppService<TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
where TEntityDto : IEntityDto<TKey>
{
protected CurdController(ITAppService appService)
: base(appService)
{
}
}
public abstract class CurdController<ITAppService, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
: CurdController<ITAppService, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TGetListInput, TCreateInput, TUpdateInput>
where ITAppService : ICurdAppService<TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
where TGetOutputDto : IEntityDto<TKey>
where TGetListOutputDto : IEntityDto<TKey>
{
protected CurdController(ITAppService appService)
: base(appService)
{
}
}
public abstract class CurdController<ITAppService, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TGetListBriefInput, TCreateInput, TUpdateInput>
: CurdController<ITAppService, TGetOutputDto, TGetListOutputDto, TGetListOutputDto, TKey, TGetListInput, TGetListBriefInput, TCreateInput, TUpdateInput>
where ITAppService : ICurdAppService<TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TGetListBriefInput, TCreateInput, TUpdateInput>
where TGetOutputDto : IEntityDto<TKey>
where TGetListOutputDto : IEntityDto<TKey>
where TGetListBriefInput : TGetListInput
{
protected CurdController(ITAppService appService)
: base(appService)
{
}
}
public abstract class CurdController<ITAppService, TGetOutputDto, TGetListOutputDto, TGetListBriefOutputDto, TKey, TGetListInput, TGetListBriefInput, TCreateInput, TUpdateInput>
: AbpControllerBase
where ITAppService : ICurdAppService<TGetOutputDto, TGetListOutputDto, TGetListBriefOutputDto, TKey, TGetListInput, TGetListBriefInput, TCreateInput, TUpdateInput>
where TGetOutputDto : IEntityDto<TKey>
where TGetListOutputDto : IEntityDto<TKey>
where TGetListBriefInput : TGetListInput
{
private readonly ITAppService _recipeAppService;
public CurdController(ITAppService recipeAppService)
{
_recipeAppService = recipeAppService;
}
[HttpPost]
[Route("Create")]
public virtual async Task<TGetOutputDto> CreateAsync(TCreateInput input)
{
return await _recipeAppService.CreateAsync(input);
}
[HttpDelete]
[Route("Delete")]
public virtual async Task DeleteAsync(TKey id)
{
await _recipeAppService.DeleteAsync(id);
}
[HttpGet]
[Route("GetAll")]
public virtual async Task<PagedResultDto<TGetListOutputDto>> GetAllAsync(TGetListInput input)
{
return await _recipeAppService.GetAllAsync(input);
}
[HttpGet]
[Route("Get")]
public virtual async Task<TGetOutputDto> GetAsync(TKey id)
{
return await _recipeAppService.GetAsync(id);
}
[HttpPut]
[Route("Update")]
public virtual async Task<TGetOutputDto> UpdateAsync(TUpdateInput input)
{
return await _recipeAppService.UpdateAsync(input);
}
[HttpGet]
[Route("GetAllBrief")]
public virtual async Task<PagedResultDto<TGetListBriefOutputDto>> GetAllBriefAsync(TGetListBriefInput input)
{
return await _recipeAppService.GetAllBriefAsync(input);
}
}
在開發業務模組時,我們可以先使用簡單的方式提供Curd服務,隨著UI複雜度增加,逐步的使用更加複雜的Curd服務。某種程度上來說,即所謂「漸進式」的開發方式。
我們擴充套件應用層基礎類別,控制器及其介面
以Alarm為例。來實現擴充套件型Curd服務(ExtendedCurd)。
假設你已完成建立實體、Dto以及設定完成AutoMapper對映
IApplicationService是ABP框架的介面,所有的應用服務都需要繼承自此介面。
public interface IAlarmAppService : IExtendedCurdAppService<AlarmDto, AlarmDto, AlarmBriefDto, long, GetAllAlarmInput, GetAllAlarmInput, CreateAlarmInput, UpdateAlarmInput>, IApplicationService
{
}
public class AlarmAppService : ExtendedCurdAppServiceBase<CAH.Health.Alarm.Alarm, AlarmDto, AlarmDto, AlarmBriefDto, long, GetAllAlarmInput, GetAllAlarmInput, CreateAlarmInput, UpdateAlarmInput>, IAlarmAppService
{
public AlarmAppService(IRepository<CAH.Health.Alarm.Alarm, long> basicInventoryRepository) : base(basicInventoryRepository)
{
}
}
[Area(HealthRemoteServiceConsts.ModuleName)]
[RemoteService(Name = HealthRemoteServiceConsts.RemoteServiceName)]
[Route("api/Health/alarm")]
public class AlarmController : ExtendedCurdController<IAlarmAppService, AlarmDto, AlarmDto, AlarmBriefDto, long, GetAllAlarmInput, GetAllAlarmInput, CreateAlarmInput, UpdateAlarmInput>, IAlarmAppService
{
private readonly IAlarmAppService _alarmAppService;
public AlarmController(IAlarmAppService alarmAppService) : base(alarmAppService)
{
_alarmAppService = alarmAppService;
}
}
執行程式
可以看到,我們的介面已經包含所有擴充套件型Curd方法。
下一章我們將實現通用查詢介面的按組織架構查詢。
本文來自部落格園,作者:林曉lx,轉載請註明原文連結:https://www.cnblogs.com/jevonsflash/p/17549794.html