验证:作为约定,Input DTO实现IInputDto 接口,Output DTO实现IOutputDto接口。当你声明IInputDto参数时, 在方法执行前ABP将会自动对其进行有效性验证。这类似于ASP.NET MVC验证机制,但是请注意应用服务并不是一个控制器(Controller)。ABP对其进行拦截并检查输入。查看DTO 验证(DTO Validation)文档获取更多信息。 EntityDto是一个简单具有与实体相同的Id属性的简单类型。如果你的实体Id不为int型你可以使用它泛型版本。EntityDto也实现了IDto接口。你可以看到PersonDto并不包含Password属性,因为展现层并不需要它。
跟进一步之前我们先实现IPersonAppService:
public class PersonAppService : IPersonAppService
{
private readonly IPersonRepository _personRepository;
public PersonAppService(IPersonRepository personRepository)
{
_personRepository = personRepository;
}
public SearchPeopleOutput SearchPeople(SearchPeopleInput input)
{
//获取实体
var peopleEntityList = _personRepository.GetAllList(person => person.Name.Contains(input.SearchedName));
//转换成DTO
var peopleDtoList = peopleEntityList
.Select(person => new PersonDto
{
Id = person.Id,
Name = person.Name,
EmailAddress = person.EmailAddress
}).ToList();
return new SearchPeopleOutput { People = peopleDtoList };
}
}
我们从数据库获取实体,将实体转换成DTO并返回output。注意我们没有手动检测Input的数据有效性。ABP会自动验证它。ABP甚至会检查Input是否为null,如果为null则会抛出异常。这避免了我们在每个方法中都手动检查数据有效性。
但是你很可能不喜欢手动将Person实体转换成PersonDto。这真的是个乏味的工作。Peson实体包含大量属性时更是如此。
DTO和实体间的自动映射
还好这里有些工具可以让映射(转换)变得十分简单。AutoMapper就是其中之一。你可以通过nuget把它添加到你的项目中。让我们使用AutoMapper来重写SearchPeople方法:
public SearchPeopleOutput SearchPeople(SearchPeopleInput input)
{
var peopleEntityList = _personRepository.GetAllList(person => person.Name.Contains(input.SearchedName));
return new SearchPeopleOutput { People = Mapper.Map<List<PersonDto>>(peopleEntityList) };
}
这就是全部代码。你可以在实体和DTO中添加更多的属性,但是转换代码依然保持不变。在这之前你只需要做一件事:映射
Mapper.CreateMap<Person, PersonDto>();
AutoMapper创建了映射的代码。这样,动态映射就不会成为性能问题。真是快速又方便。AutoMapper根据Person实体创建了PersonDto,并根据命名约定来给PersonDto的属性赋值。命名约定是可配置的并且很灵活。你也可以自定义映射和使用更多特性,查看AutoMapper的文档获取更多信息。








