Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

Índice

Em grande parte de nosso sistema, muitas telas precisam conter apenas uma lógica de CRUD básica (

CrudAppService e AsyncCrudAppService Classes

Se você precisa criar um serviço de aplicação que terá uma operação de CRUD (acrônimo de Create, Read, Update e Delete) para uma entidade especifica.

Visando uma maior produtividade, o TNF contém duas classes para agilizar esses processo: CrudAppService e AsyncCrudAppService.

Como essas classes são facilitadores, neste modelo não possui nenhuma implementação na camada de domínio. As validações são geradas em cima dos objetos que fazem o mapeamento com o banco de dados (Country) e DTOs (CountryDto).

trás classes que agilizam essa criação de serviços de forma automática.

Para utilizar essas funcionalidades instale via nuget o pacote Tnf.App.EntityFrameworkCore disponível em: https://www.myget.org/F/tnf/api/v3/index.json

Definindo um Serviço de CRUD

Primeiro vamos criar nossa interface para o serviço de aplicação definindo sua herança para a interface IAppApplicationService<PersonDto, GetAllPeopleDto> informando qual o Dto será usado para o mapeamento da entidade, e qual o Dto para métodos de GetAllA entidade abaixo realiza o mapeamento da tabela Countries para o Entity Framework Core:

Bloco de código
languagec#
firstline1
titleCountryIPersonAppService.cs
linenumberstrue
public interface IPersonAppService : IAppApplicationService<PersonDto, GetAllPeopleDto>
{
}

Criando DTO e Entidade

Dto:

Bloco de código
languagec#
firstline1
titlePersonDto.cs
linenumberstrue
[AutoMap(typeof(CountryDto))]
[Table("Countries")]
public class CountryPersonDto : EntityDtoBase
{
    public conststatic intPersonDto MaxNameLengthNullInstance = 256;
    [Required]
    [MaxLength(MaxNameLength)]
new PersonDto().AsNullable();

    public string Name { get; set; }

    public enum Error
    {
        GetAllPeople = 1,
        GetPerson = 2,
        PostPerson = 3,
        PutPerson = 4,
        DeletePerson = 5
    }
}


Entidade:

Bloco de código
languagec#
firstline1
titlePerson.cs
linenumberstrue
[AutoMap(typeof(CountryDto))]
public class Person : Entity
{
    public string Name { get; set; }


    public CountryPerson()
    {
    }

    public CountryPerson(int id, string name)
    {
        Id = id;
        Name = name;
    }
}

...


    public enum Error
    {
        PersonNameMustHaveValue = 1
    }
}

Até este ponto temos nossa definição de serviço (interface), Dto criado e Entidade no Entity Framework Core representada.

Essa especificação garante que ao utilizar o serviço de CRUD irá usar o Mapper automático das propriedades pra classe de infraestrutura e Dto.

Para utilizar o AutoMapper consulte o tópico de Mapeamento Automático de Entidades.

Implementando o Serviço de Aplicação

Bloco de código
languagec#
firstline1
titleCountryDtoPersonAppService.cs
linenumberstrue
public class CountryDtoPersonAppService : AppApplicationService, CustomValidateIPersonAppService
{
    private readonly IAppDomainService<Person> _service;

    public string Name { get; set;PersonAppService(IAppDomainService<Person> service)
    {
    	_service = service;
    }

    public override void AddValidationErrors(CustomValidationContext context IListDto<PersonDto, int> GetAll(GetAllPeopleDto request)
        => _service.GetAll<PersonDto>(request, p => request.Name.IsNullOrEmpty() || p.Name.Contains(request.Name));

    public PersonDto Get(IRequestDto<int> id)
    {
    	ValidateRequestDto(id, nameof(id));

        if (string.IsNullOrWhiteSpace(Name))
   Notification.HasNotification())
        	return PersonDto.NullInstance;

        var entity = _service.Get(id);
        return entity.MapTo<PersonDto>();
 	}

    public PersonDto Create(PersonDto person)
    {
    	ValidateDto(person, nameof(person));

        if context.Results.Add(new ValidationResult("Name is required"));
(Notification.HasNotification())
        	return PersonDto.NullInstance;

        var personBuilder = new PersonBuilder(Notification)
     		.WithId(person.Id)
            .WithName(person.Name);

       	person.Id  }
   }
}

Definição da interface do serviço de aplicação:

Bloco de código
languagec#
firstline1
titleICountryAppService.cs
linenumberstrue
public interface ICountryAppService : IAsyncCrudAppService<CountryDto>
{
}

Implementação do serviço de aplicação informando qual a entidade, DTO e realizando a herança da classe AsyncCrudAppService que irá definir que este serviço contem as funcionalidades de CRUD presentes no TNF:

Bloco de código
languagec#
firstline1
titleCountryAppService.cs
linenumberstrue
public class CountryAppService : AsyncCrudAppService<Country, CountryDto>, ICountryAppService
{
    public CountryAppService(IRepository<Country> repository)
= _service.InsertAndGetId(personBuilder);

        return person;
  	}

    public PersonDto Update(int id, PersonDto person)
    {
    	ValidateDtoAndId(person, id, nameof(person), nameof(id));

        if (Notification.HasNotification())
        	return PersonDto.NullInstance;

        var personBuilder = new PersonBuilder(Notification)
        	.WithId(id)
            .WithName(person.Name);

        _service.Update(personBuilder);

        person.Id = id;
        return person;
   }

    public void Delete(int id)
    {
    	ValidateId(id, nameof(id));

        : base(repositoryif (Notification.HasNotification())
     {
    	return;

        _service.Delete(id);
   }
}

Note que o serviço recebe como parâmetro um repositório de dados para a entidade Country. Quem define a implementação para a interface IRepository neste exemplo é um nuget package do TNF que contém uma implementação de repositório para o Entity Framework Core chamado: "Tnf.App.EntityFrameworkCore".

O repositório padrão realiza o mapeamento da entidade automaticamente para o seu respectivo DTO através de outros pacotes chamados: Tnf.AutoMapper e Tnf.Dto.

a definição do serviço se da pela herança da classe IAppDomainService<Person> onde é passado a Entidade do Entity Framework Core.

Após a definição acima o serviço de aplicação pode ser usado normalmente.

A interface IAppApplicationService<PersonDto, GetAllPeopleDto> expõe os métodos de CRUD no formato síncrono. Também existe a versão assíncrona do serviço de CRUD usando a interface IAppAsyncApplicationService<PersonDto, GetAllPeopleDto>.Ambos os pacotes podem ser obtidos através de nosso feed de pacotes: https://www.myget.org/F/tnf/api/v3/index.json