ABP (ASP.NET Boilerplate) 應用程式開發框架 新手教學 No.6 建立應用服務
ABP (ASP.NET Boilerplate) 應用程式開發框架 新手教學 No.0 索引
應用服務主要是表現層與領域層中間溝通的橋樑,提供了服務給表現層調用,讓表現層與領域層的耦合降低
另外在這層也提供了資料傳輸物件(DTO),來與表現層互相傳遞資料,主要是Input與Output部分
首先我們一樣案架構來到應用服務層MyCompany.MyProject.Application專案
建立PlayerApp資料夾(命名規則:xxxxxApp)來放我們的服務 (介面 IPlayerAppService、類別 PlayerAppService)
其中建立DTO資料夾來放基本DTO與輸入/輸出DTO (PlayerDto、PlayerInput、PlayerOptput)
MyCompany.MyProject.Application\PlayerApp\Dto\PlayerDto.cs
using Abp.Application.Services.Dto;
namespace MyCompany.MyProject.PlayerApp.Dto
{
public class PlayerDto : EntityDto<long>
{
public long PlayerID { get; set; }
public string PlayerName { get; set; }
public long MapID { get; set; }
}
}
PlayerInput.cs
using Abp.Application.Services.Dto;
using Abp.Runtime.Validation;
using System.ComponentModel.DataAnnotations;
namespace MyCompany.MyProject.PlayerApp.Dto
{
public class PlayerInput : IInputDto
{
public long PlayerID { get; set; }
public string PlayerName { get; set; }
public long MapID { get; set; }
}
public class GetPlayerInput : IInputDto
{
public string PlayerName { get; set; }
public long MapID { get; set; }
}
public class CreatePlayerInput : IInputDto, IShouldNormalize
{
[Required]
public string PlayerName { get; set; }
public long MapID { get; set; }
public void Normalize()
{
if (MapID == 0)
{
MapID = 1;
}
}
}
}
這裡可以利用 System.ComponentModel.DataAnnotations 來用 [Required] 標記
而因為我們繼承了IInputDto,該介面又繼承了IValidate,所以ABP會自動替我們做驗證
標準化:IShouldNormalize定義了必須實作標準化方法Normalize()
在驗證完成後會自動跑裡面的設定,處理屬性為空時給定預設值之類的BaLaBaLaBaLa
PlayerOptput.cs
using Abp.Application.Services.Dto;
using System.Collections.Generic;
namespace MyCompany.MyProject.PlayerApp.Dto
{
public class PlayerOutput : IOutputDto
{
public long MapID { get; set; }
public string PlayerName { get; set; }
}
public class GetPlayersOutput : IOutputDto
{
public List<PlayerDto> Players { get; set; }
}
}
到這邊DTO基本就建立完成,再來是Service部分
首先是 服務(Service) 介面定義,命名規則使用 I+實體名稱(單數)+AppService
建立介面 IPlayerAppService.cs
MyCompany.MyProject.Application\PlayerApp\IPlayerAppService.cs
using Abp.Application.Services;
using MyCompany.MyProject.PlayerApp.Dto;
namespace MyCompany.MyProject.PlayerApp
{
public interface IPlayerAppService : IApplicationService
{
GetPlayersOutput GetPlayers(GetPlayerInput input);
void UpdatePlayer(PlayerInput input);
void CreatePlayer(PlayerInput input);
}
}
實作介面
PlayerAppService.cs
using Abp.UI;
using AutoMapper;
using MyCompany.MyProject.Entities;
using MyCompany.MyProject.IRepositories;
using MyCompany.MyProject.PlayerApp.Dto;
using System.Collections.Generic;
namespace MyCompany.MyProject.PlayerApp
{
public class PlayerAppService : MyProjectAppServiceBase, IPlayerAppService
{
private readonly IPlayerRepository _playerRepository;
public PlayerAppService(IPlayerRepository playerRepository)
{
_playerRepository = playerRepository;
}
public void CreatePlayer(PlayerInput input)
{
var playerEntity = _playerRepository.FirstOrDefault(player => player.PlayerName.Equals(input.PlayerName));
if (playerEntity != null)
throw new UserFriendlyException("該玩家數據已經存在!");
else
{
playerEntity = new Player()
{
PlayerName = input.PlayerName,
MapID = 1
};
_playerRepository.Insert(playerEntity);
}
}
public GetPlayersOutput GetPlayers(GetPlayerInput input)
{
if (!string.IsNullOrEmpty(input.PlayerName))
{
//Get entities
var playerEntityList = _playerRepository.GetAllList(player => player.PlayerName.Contains(input.PlayerName));
//Convert to DTOs
return new GetPlayersOutput { Players = Mapper.Map<List<PlayerDto>>(playerEntityList) };
}
if (input.MapID > 0)
{
//Get entities
var playerEntityList = _playerRepository.GetPlayersWithMap(input.MapID);
//Convert to DTOs
// 用AutoMapper自動將List<Task>轉換成List<TaskDto>
return new GetPlayersOutput
{
Players = Mapper.Map<List<PlayerDto>>(playerEntityList)
};
}
throw new UserFriendlyException("參數有誤!");
}
public void UpdatePlayer(PlayerInput input)
{
Logger.Info(" Updating a Player for input: " + input);
var playerEntity = _playerRepository.Get(input.PlayerID);
if (playerEntity == null)
throw new UserFriendlyException("該玩家數據不存在!");
if (!string.IsNullOrEmpty(input.PlayerName))
{
playerEntity.PlayerName = input.PlayerName;
}
if (input.MapID > 0)
{
playerEntity.MapID = input.MapID;
}
}
}
}
到這邊就完成了應用服務層
下一篇
ABP (ASP.NET Boilerplate) 應用程式開發框架 新手教學 No.7 建立WebApi
參照