5.3 KiB
Web Application Development Tutorial - Part 8: Authors: Application Layer
//[doc-params]
{
"UI": ["MVC","NG"],
"DB": ["EF","Mongo"]
}
{{ if UI == "MVC" UI_Text="mvc" else if UI == "NG" UI_Text="angular" else UI_Text="?" end if DB == "EF" DB_Text="Entity Framework Core" else if DB == "Mongo" DB_Text="MongoDB" else DB_Text="?" end }}
About This Tutorial
In this tutorial series, you will build an ABP based web application named Acme.BookStore. This application is used to manage a list of books and their authors. It is developed using the following technologies:
- {{DB_Text}} as the ORM provider.
- {{UI_Value}} as the UI Framework.
This tutorial is organized as the following parts;
- Part 1: Creating the server side
- Part 2: The book list page
- Part 3: Creating, updating and deleting books
- Part 4: Integration tests
- Part 5: Authorization
- Part 6: Authors: Domain layer
- Part 7: Authors: Database Integration
- Part 8: Author: Application Layer (this part)
Download the Source Code
This tutorials has multiple versions based on your UI and Database preferences. We've prepared two combinations of the source code to be downloaded:
Introduction
This part explains to create an application layer for the Author entity created before.
IAuthorAppService
We will first create the application service interface and the related DTOs. Create a new interface, named IAuthorAppService, in the Authors namespace (folder) of the Acme.BookStore.Application.Contracts project:
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Acme.BookStore.Authors
{
public interface IAuthorAppService : IApplicationService
{
Task<AuthorDto> GetAsync(Guid id);
Task<PagedResultDto<AuthorDto>> GetListAsync(GetAuthorListDto input);
Task<AuthorDto> CreateAsync(CreateAuthorDto input);
Task UpdateAsync(Guid id, UpdateAuthorDto input);
Task DeleteAsync(Guid id);
}
}
IApplicationServiceis a conventional interface that is inherited by all the application services, so the ABP Framework can identify the service.- Defined standard methods to perform CRUD operations on the
Authorentity. PagedResultDtois a pre-defined DTO class in the ABP Framework. It has anItemscollection and aTotalCountproperty to return a paged result.- Preferred to return an
AuthorDto(for the newly created author) from theCreateAsyncmethod, while it is not used by this application - just to show a different usage.
This interface is using the DTOs defined below.
AuthorDto
using System;
using Volo.Abp.Application.Dtos;
namespace Acme.BookStore.Authors
{
public class AuthorDto : EntityDto<Guid>
{
public string Name { get; set; }
public DateTime BirthDate { get; set; }
public string ShortBio { get; set; }
}
}
EntityDto<T>simply has anIdproperty with the given generic argument. You could create anIdproperty yourself instead of inheriting theEntityDto<T>.
GetAuthorListDto
using Volo.Abp.Application.Dtos;
namespace Acme.BookStore.Authors
{
public class GetAuthorListDto : PagedAndSortedResultRequestDto
{
public string Filter { get; set; }
}
}
Filteris used to search authors. It can benull(or empty string) to get all the authors.PagedAndSortedResultRequestDtohas the standard paging and sorting properties:int MaxResultCount,int SkipCountandstring Sorting.
ABP Framework has such base DTO classes to simplify and standardize your DTOs. See the DTO documentation for all.
CreateAuthorDto
using System;
using System.ComponentModel.DataAnnotations;
namespace Acme.BookStore.Authors
{
public class CreateAuthorDto
{
[Required]
[StringLength(AuthorConsts.MaxNameLength)]
public string Name { get; set; }
[Required]
public DateTime BirthDate { get; set; }
public string ShortBio { get; set; }
}
}
Data annotation attributes can be used to validate the DTO. See the validation document for details.
UpdateAuthorDto
using System;
using System.ComponentModel.DataAnnotations;
namespace Acme.BookStore.Authors
{
public class UpdateAuthorDto
{
[Required]
[StringLength(AuthorConsts.MaxNameLength)]
public string Name { get; set; }
[Required]
public DateTime BirthDate { get; set; }
public string ShortBio { get; set; }
}
}
We could share (re-use) the same DTO among the create and the update operations. While you can do it, we prefer to create different DTOs for these operations since we see they generally be different by the time. So, code duplication is reasonable here compared to a tightly coupled design.