Building an application-tier service

Source: Internet
Author: User
Tags app service

Back to the general catalogue "Step by step using the ABP framework to build a formal project series tutorial"

Talk today about building application-level services.

Theoretical study:

App service provides some façade style methods to separate the presentation and domain layers. The purpose of this is to understand the decoupling, and later the presentation layer does not have to deal directly with the business logic layer (the core layer), but through the Application service layer (equivalent to the media) to deal with. The Application service layer not only defines a number of service methods for direct invocation by the presentation layer, but also provides some dtos (Data Transfer Object).

When it comes to DTOs, there are a lot of benefits.

First, it can be understood as a simplified entity and more convenient. For example, we have a user table with Id,name,password,isdeleted,creationtime and so on. Then our simplified Userdto object contains only the name and the IsDeleted two fields, because the presentation layer only uses these two fields.

Second, more secure and better performance. If you use an entity class without a DTO, the last query generated will query all the fields of the entity. This exposes some important data to those we don't want the data to be seen.

Thirdly, the application of expansibility is better and the coupling degree is reduced. The presentation layer invokes the application service method through a Dto object as a parameter, then executes the specific business logic using the domain object (the entity class object) and returns a Dto object to the presentation layer, so the presentation layer is completely independent of the domain layer. In an ideal application, the presentation layer and the domain layer do not interact directly.

The four, the serialization problem. 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 might be serialized into JSON and sent to the client. If you return an entity, there will be a problem. For example, the user entity has a role application that serializes a role if it is to serialize the user. Even role might have list<permission>,permission and a permissiongroup quote and so on ... Do you dare to imagine the object after serialization? It is also easy to serialize the entire database at once. Therefore, it is a good practice to return a specially designed dtos that is safe and serialized in this case.

To define DTOs first, look at the following code:

namespacenoah.chargestation.application.citiesapp.dto{ Public classCityinput:iinputdto { Public stringName {Get;Set; }  Public stringCode {Get;Set; }  Public stringProvincecode {Get;Set; } }     Public classGetcityinput:iinputdto { Public stringName {Get;Set; }  Public stringProvincecode {Get;Set; } }     Public classCreatecityinput:iinputdto, ishouldnormalize {[Required] Public stringName {Get;Set; } [Required] Public stringCode {Get;Set; } [Required] Public stringProvincecode {Get;Set; }  PublicDateTime Updatedtime {Get;Set; }  Public stringUpdatedby {Get;Set; }  Public voidNormalize () {if(updatedtime==NULL) {Updatedtime=DateTime.Now; }        }    }}

This is the input direction of the DTO, the implementation of the Iinputdto interface, so that ABP can automatically help us to verify the data. Of course, we can also add data annotations for validation. After validation, you can also implement the Ishouldnormalize interface to set the default value.

namespacenoah.chargestation.application.citiesapp.dto{ Public classCityoutput:ioutputdto { Public stringCode {Get;Set; }  Public stringName {Get;Set; }  Public stringProvincecode {Get;Set; } }     Public classGetcitiesoutput:ioutputdto { PublicList<citydto> Cities {Get;Set; } }}

The above is the DTO in the output direction.

Next I define a city table's service interface Icityappservice, and my naming convention is "i+ entity class singular +appservice".

namespace noah.chargestation.application.citiesapp{    publicinterface  icityappservice:i Applicationservice    {        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 available in both synchronous and asynchronous versions of two.

Next implement the Application service interface, here only one method GetCities (...), Hope Reader extrapolate.

 Public classCityappservice:chargestationappservicebase, Icityappservice {Private ReadOnlyIrepository<cities>_cityrepository;  PublicCityappservice (irepository<cities>cityrepository) {_cityrepository=cityrepository; }         Publicgetcitiesoutput getcities (getcityinput input) {//query for different results based on different criteria//mapper.createmap<cities, cityoutput> (); //Query City data by city name            if(!string. IsNullOrEmpty (input. Name)) {varCityentity = _cityrepository.getalllist (c = c.name = =input. Name).                FirstOrDefault (); return NewGetcitiesoutput () {citydto = mapper.map<citydto>(cityentity)}; }            //Query City data by province code            if(!string. IsNullOrEmpty (input. Provincecode)) {varCityentitylist = _cityrepository.getalllist (c = C.provincecode = =input.                Provincecode); return NewGetcitiesoutput () {citydtolist = mapper.map<list<citydto>>(Cityentitylist)}; }            return NULL; }         Public voidupdatecity (Cityinput input) {Logger.info ("Updating a city for input:"+input); }         Public voidcreatecity (Cityinput input) {//var city = _cityrepository.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);        }         PublicTask<getcitiesoutput>getcitiesasync (Getcityinput input) {Throw Newsystem.notimplementedexception (); }         PublicTask updatecityasync (cityinput input) {Throw Newsystem.notimplementedexception (); }         PublicTask createcityasync (cityinput input) {Throw Newsystem.notimplementedexception (); }    }

There's a new thing here. AutoMapper, regarding the use of this, I will open a special topic on automapper these days, please look forward to. The code is not difficult, and it doesn't explain much. Let's get here today. I'll talk about it next time.

Building an application-tier service

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.