Build an application layer service and an Application Layer

Source: Internet
Author: User

Build an application layer service and an Application Layer
Go back to the General Directory, "Step by Step Using the ABP framework to build a formal project series tutorial"

Let's talk about building an application-layer service today.

Theoretical Study:

The Application Service provides several facade styles to separate the presentation layer from the domain layer. This is also intended for decoupling. In the future, the presentation layer does not have to deal with the business logic layer (core layer) directly, but is processed through the application service layer (equivalent to the media. The application service layer not only defines many service methods for direct calling by the presentation layer, but also provides some Dtos (Data Transfer Object ).

When it comes to Dto, there are indeed many benefits.

First, it can be understood as a simplified entity, which is more convenient. For example, we have a User table containing Id, Name, Password, IsDeleted, CreationTime, and so on. The simplified UserDto object can only contain the Name and IsDeleted fields, because the presentation layer only uses these two fields.

Second, it is safer and has better performance. If the object class is used without Dto, all fields of the object will be queried in the final generated query. In this way, some important data is exposed to people we don't want to see.

Third, the application has better scalability and lower Coupling Degree. The presentation layer uses a Dto object as a parameter to call the application service method. Then, the domain object (entity-Class Object) is used to execute specific business logic and a Dto object is returned to the presentation layer, therefore, the presentation layer is completely independent of the domain layer. In an ideal application, the presentation layer and the domain layer do not directly deal with each other.

Fourth, serialization problems. When a data object is returned to the presentation layer, it is likely to be serialized somewhere. For example, in an MVC method that returns JSON, your object may be serialized into Json and sent to the client. If an object is returned, the problem may occur. For example, this User entity has a Role application. to serialize a User, the Role will also be serialized. Even the Role may have a List <Permission>, A PermissionGroup reference, and so on... Do you dare to imagine the serialized object? You can also serialize the entire database at once easily. Therefore, returning a security serialized, specially designed DTOs is a good practice in this case.

Let's first define Dtos and look at the following code:

namespace Noah.ChargeStation.Application.CitiesApp.Dto{    public class CityInput : IInputDto    {        public string Name { get; set; }        public string Code { get; set; }        public string ProvinceCode { get; set; }    }    public class GetCityInput : IInputDto    {        public string Name { get; set; }        public string ProvinceCode { get; set; }    }    public class CreateCityInput : IInputDto, IShouldNormalize    {        [Required]        public string Name { get; set; }        [Required]        public string Code { get; set; }        [Required]        public string ProvinceCode { get; set; }        public DateTime UpdatedTime { get; set; }        public string UpdatedBy { get; set; }        public void Normalize()        {            if (UpdatedTime==null)            {                UpdatedTime=DateTime.Now;            }        }    }}

This is the Dto in the input direction and implements the IInputDto interface. In this way, the ABP can automatically help us perform data verification. Of course, we can also add data annotations for verification. After verification, you can also implement the IShouldNormalize interface to set the default value.

namespace Noah.ChargeStation.Application.CitiesApp.Dto{    public class CityOutput:IOutputDto    {        public string Code { get; set; }        public string Name { get; set; }        public string ProvinceCode { get; set; }    }    public class GetCitiesOutput:IOutputDto    {        public List<CityDto> Cities { get; set; }    }}

The preceding figure shows the Dto in the output direction.

 

Next I will define the service interface ICityAppService for a city table. My naming convention is "I + entity Class Singular + AppService ".

namespace Noah.ChargeStation.Application.CitiesApp{    public interface ICityAppService:IApplicationService    {        GetCitiesOutput GetCities(GetCityInput input);        Task<GetCitiesOutput> GetCitiesAsync(GetCityInput input);        void UpdateCity(CityInput input);        Task UpdateCityAsync(CityInput input);        void CreateCity(CityInput input);        Task CreateCityAsync(CityInput input);    }}
The methods defined above are synchronous and asynchronous.

Next we will implement the application service interface. Here we only implement the GetCities (…) method (...), I hope the readers can draw a line from each other.

Public class CityAppService: libraries, ICityAppService {private readonly IRepository <Cities> _ libraries; public CityAppService (IRepository <Cities> libraries) {_ libraries = libraries;} public GetCitiesOutput GetCities (GetCityInput input) {// query different results based on different conditions // Mapper. createMap <Cities, CityOutput> (); // query city data by city name if (! String. isNullOrEmpty (input. name) {var cityEntity = _ cityRepository. getAllList (c => c. name = input. name ). firstOrDefault (); return new GetCitiesOutput () {CityDto = Mapper. map <CityDto> (cityEntity) };}// query city data by province code if (! String. isNullOrEmpty (input. provinceCode) {var cityEntityList = _ cityRepository. getAllList (c => c. provinceCode = input. provinceCode); return new GetCitiesOutput () {CityDtoList = Mapper. map <List <CityDto> (cityEntityList) };} return null;} public void UpdateCity (CityInput input) {Logger. info ("Updating a City for input:" + input);} public void CreateCity (CityInput input) {// var city = _ cityRe Pository. FirstOrDefault (c => c. Name = input. Name); // if (city! = Null) // {// throw new UserFriendlyException ("the city data already exists! "); //} // City = new City () {Code = input. code, Name = input. name, ProvinceCode = input. provinceCode}; // _ cityRepository. insert (city);} public Task <GetCitiesOutput> GetCitiesAsync (GetCityInput input) {throw new System. notImplementedException ();} public Task UpdateCityAsync (CityInput input) {throw new System. notImplementedException ();} public Task CreateCityAsync (CityInput input) {throw new System. notImplementedException ();}}

Here is a new feature called AutoMapper. I will discuss this topic in the past few days. There is no difficulty in the code, so I will not explain it much. Let's get there today. Next time.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.