& Lt; ABP framework & gt; Data Transmission object, abp framework

Source: Internet
Author: User
Tags automap

<ABP framework> data transmission object, abp framework

Document directory

 

Content of this section:

  • DTO necessity
    • Abstraction at the Domain Layer
    • Data Hiding
    • Serialization and delayed Loading
  • DTO conventions and Verification
    • Example
  • Automatic ing between DTO and Object
    • Ing using features and extension methods
  • Auxiliary interfaces and Classes

 

Data Transfer Objects (DTO) is used to transmit Data between the application layer and the presentation layer.

The presentation layer uses a DTO to call an application service method. Then, the application service executes some specific business logic using the service object and returns a DTO to the presentation layer. Therefore, the presentation layer is completely independent from the domain layer. In an ideal layered application, the presentation layer does not directly use domain objects (warehousing, entities ...).

 

DTO necessity

Creating a DTO for each application service method seems tedious and time-consuming, but if you use it correctly, it can save your application. Why?

 

Abstraction at the Domain Layer

Dto provides an effective way to abstract domain objects from the presentation layer. Therefore, your layer is split correctly, even if you want to completely change the presentation layer, you can also continue to use the existing application and domain layer. On the contrary, you can rewrite your domain layer, completely change the database structure, entity, and ORM framework, as long as your application service contract (method signature and DTO) remains unchanged, the presentation layer does not need to be modified.

 

Data Hiding

Consider: You have a User entity that has attributes such as Id, Name, EmailAddress, and Password. If the GetAllusers () method of UserAppService returns a List <User>, anyone can see the password of all users, even if you do not show it on the screen, it is not safe. In addition to data security and data hiding, the application service should only return the necessary data to the presentation layer.

 

Serialization and delayed Loading

When you return a data (an object) to the presentation layer, it may be serialized somewhere. For example, in an MVC method that returns Json, your object will be serialized into JSON and sent to the client. In this case, if an object is returned to the presentation layer, the problem may occur. Why?

In a real application, your entities may reference each other, and User entities may be associated with Roles. Therefore, if you want to serialize a User, its Roles will also be serialized, the Role class may contain a List <Permission>, and the Permission class may be associated with the PermissionGroup class. You can think of serialization of these objects. You may accidentally serialize your entire database. If your object has a circular reference, it cannot be serialized.

How can this problem be solved? Mark attributes as NonSerialized (not serialized )? No, you don't know when it should be serialized and when it should not be serialized. It may be serialized in this application service, but not in another service, therefore, a safe and serializable response is returned. The specially designed DTO is a good choice.

Almost all ORM frameworks support delayed loading, which is a feature for loading entities from the database as needed. Assume that the User class has a reference pointing to the Role class. When you get a User from the database, the Role attribute is not filled. When you read the Role attribute for the first time, it is loaded from the database. Therefore, if you return such an object to the presentation layer, it will obtain additional entities from the database. If a serialization tool reads this entity, it recursively reads all attributes and may serialize your entire database (if there is an appropriate relationship between entities ).

We can say that there are more issues with the use of entities in the presentation layer. The best practice is to not reference the Assembly containing the domain (business) layer in the application layer.

 

DTO conventions and Verification

ABP strongly supports DTO. It provides some convention classes and interfaces, and recommends some naming and usage conventions. When you write code as described in this section, some tasks are automatically completed by the ABP.

 

Example

Let's take a complete example. Suppose we want to develop an application service that searches for people by name and returns a people list. In this way, we should have a Person entity, such:

public class Person : Entity{    public virtual string Name { get; set; }    public virtual string EmailAddress { get; set; }    public virtual string Password { get; set; }}

Next, define an interface for our application service:

public interface IPersonAppService : IApplicationService{    SearchPeopleOutput SearchPeople(SearchPeopleInput input);}

We recommend that you name the input/output parameters as follows: MethodNameInputAnd MethodNameOutputAnd define separate input and input DTO for each application service method. Even if your method only accepts/returns one parameter, it is best to create a DTO class. Because your code may need to be extended in the future, you can add more attributes later, you do not need to modify the signature of your method or interrupt your existing client application.

Of course, if your method does not return a value, that is, void, if you add a return value later, it will not interrupt an existing application. If your method does not have a parameter, you do not need to define an input DTO, But if you may add a parameter in the future, you 'd better add an input DTO class first, depending on you.

Let's take a look at the input and output DTO classes in this example:

public class SearchPeopleInput{    [StringLength(40, MinimumLength = 1)]    public string SearchedName { get; set; }}public class SearchPeopleOutput{    public List<PersonDto> People { get; set; }}public class PersonDto : EntityDto{    public string Name { get; set; }    public string EmailAddress { get; set; }}

Before the method starts to run, the ABP will automatically verify the input, which is similar to Asp.net Mvc verification, but note: The application service is not a controller, It is a pure C # class, this API intercepts it and automatically checks the input. There are many verifications. Please refer to the DTO verification documentation.

EntityDto is a simple class that only defines the Id attribute for an object. If you have an object primary key instead of an int, you can use it in a generic version. You do not need EntityDto, but it is best to define an Id attribute.

As you can see, PersonDto does not include the Password attribute, because the display layer does not need it and it is dangerous to send the Password of all users to the display layer. Imagine: A Javascript client requests it, anyone can easily get all the passwords.

Before proceeding, let's implement IPersonAppService:

public class PersonAppService : IPersonAppService{    private readonly IPersonRepository _personRepository;    public PersonAppService(IPersonRepository personRepository)    {        _personRepository = personRepository;    }    public SearchPeopleOutput SearchPeople(SearchPeopleInput input)    {        //Get entities        var peopleEntityList = _personRepository.GetAllList(person => person.Name.Contains(input.SearchedName));        //Convert to DTOs        var peopleDtoList = peopleEntityList            .Select(person => new PersonDto                                {                                    Id = person.Id,                                    Name = person.Name,                                    EmailAddress = person.EmailAddress                                }).ToList();        return new SearchPeopleOutput { People = peopleDtoList };    }}

We get entities from the database, convert them to DTO, and then return them to the output. Note: we have not verified the input, and it has been verified by the ABP. It even verifies whether the input parameter is null, if it is null, an exception is thrown, which saves writing verification code in each method.

However, you may not like writing code that converts a Person object into a PersonDto object. It is indeed a tedious task. The Person object may contain many attributes.

 

Automatic ing between DTO and Object

Fortunately, there are tools to make it easy. AutoMapper is one of them, and it is released on nuget. You can easily add it to your project. Let's use AutoMap to write the SearchPeople method again:

public SearchPeopleOutput SearchPeople(SearchPeopleInput input){    var peopleEntityList = _personRepository.GetAllList(person => person.Name.Contains(input.SearchedName));    return new SearchPeopleOutput { People = Mapper.Map<List<PersonDto>>(peopleEntityList) };}

This is the end of the process. You can add more attributes to the object and DTO, but the conversion code does not need to be modified. The only thing you need to do is to define a ing before using it:

Mapper.CreateMap<Person, PersonDto>();

AutoMapper creates the ing code. Therefore, dynamic ing does not cause performance problems. It is fast and easy. AutoMapper creates a PersonDto for the Person object and assigns a value to the attributes of the DTO according to the naming conventions. Naming Conventions can be complex and configuration. You can also define your own configurations and more content. For more information, see the AutoMapper documentation.

You can define the ing in PostInitialzie in your module.

 

Ing using features and extension methods

You can use multiple features and extended methods to define mappings. To use these features, add the relevant features to your project. autoMapper nuget package, and then use the AutoMap feature for Bidirectional ing, AutoMapFrom and AutoMapTo for unidirectional ing. Use the MapTo Extension Method to map one object to another. Ing definition example:

[AutoMap (typeof (MyClass2)] // defines bidirectional public ing of public class MyClass1 {public string TestProp {get; set ;}} public class MyClass2 {public string TestProp {get; set ;}}

Then you can map them using the MapTo extension method:

Var obj1 = new MyClass1 {TestProp = "Test value"}; var obj2 = obj1.MapTo <MyClass2> (); // create a new MyClass2 object and copy TestProp from obj1

The above Code creates a new MyClass2 object from a MyClass1 object. Similarly, You can map an existing object as follows:

Var obj1 = new MyClass1 {TestProp = "Test value"}; var obj2 = new MyClass2 (); obj1.MapTo (obj2); // set the obj2 attribute from obj1

 

Auxiliary interfaces and Methods

ABPS provides some auxiliary interfaces to standardize the common DTO attribute names when implemented.

ILimitedResultRequest defines the MaxResultCount attribute, so you can implement it in your input DTO class to standardize and limit the result set.

IPagedResultRequst extends ILimitedResultRequest and adds SkipCount. So we can implement it for SearchPeopleInput. The help page is:

public class SearchPeopleInput : IPagedResultRequest{    [StringLength(40, MinimumLength = 1)]    public string SearchedName { get; set; }    public int MaxResultCount { get; set; }    public int SkipCount { get; set; }}

As a paging result, you can return an output DTO that implements IHasTotalCount. Naming standardization helps us create reusable code and conventions. You can view other interfaces and classes in the Abp. Application. Services. Dto namespace.

 

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.