Árvore de páginas

Versões comparadas

Chave

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

Quando falamos de camada de aplicação estamos falando da camada responsável por coordenar a entrada de informações, controlar acesso a funcionalidades, interligando ao nosso domínio de negocio e devolvendo a resposta em um formato que a aplicação espera.

Ela ainda pode fazer o controle de transação, além de poder enviar notificações para outros softwares, Injeção da dependência de determinadas fontes de dados.

Essa camada é a principal responsável por fazer a ligação de nossas regras de negocio com nossa infraestrutura de dados: Bancos relacionais, NoSQL, Serviços externos, etc.

Podemos defini-la como uma camada coordenadora de operações de negócio.

Pensa que poderíamos ter todas as nossas regras de negócio centralizadas em um único assembly, mas N camada de aplicação para N aplicações.

Nos tópicos a seguir vamos abordar alguns aspectos quando trabalhamos com essa camada:

Índice

Serviços de aplicação são usados para expor a lógica de domínio para a camada de apresentação.

Essa camada tem como principal objetivo aplicar todas as regras definidas para uma entidade ou para um processo, mantendo o domínio do negocio isolado fazendo a ligação da lógica do negocio com sua infraestrutura de dados.

IApplicationService Interface

No TNF a interface de um serviço de aplicação deve implementar IApplicationService. Essa interface já será registrada automaticamente no container de injeção de dependência através das convenções:

Bloco de código
languagec#
firstline1
titleDefinição da interface do serviço de aplicação
linenumberstrue
public interface ITaskAppService : IApplicationService
{
    void CreateTask(CreateTaskInput input);
}
ApplicationService Class

Um serviço de aplicação deveria implementar a interface declarada acima. Toda implementação de um serviço de aplicação deve derivar da classe ApplicationService. 

Essa classe expõe funcionalidades pré-definidas dentro da aplicação que facilitam seu uso como logging, localization:

Bloco de código
languagec#
firstline1
titleImplementação do serviço de aplicação
linenumberstrue
public class TaskAppService : ApplicationService, ITaskAppService
{
    public TaskAppService()
    {
        LocalizationSourceName = "SimpleTaskSystem";
    }

    public void CreateTask(CreateTaskInput input)
    {
        // Write some logs (Logger is defined in ApplicationService class)
        Logger.Info("Creating a new task with description: " + input.Description);

        // Get a localized text (L is a shortcut for LocalizationHelper.GetString(...), defined in ApplicationService class)
        var text = L("SampleLocalizableTextKey");

        // TODO: Add new task to database...
    }
}
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, 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).

A entidade abaixo realiza o mapeamento da tabela Countries para o Entity Framework Core:

Bloco de código
languagec#
firstline1
titleCountry.cs
linenumberstrue
[AutoMap(typeof(CountryDto))]
[Table("Countries")]
public class Country : Entity
{
    public const int MaxNameLength = 256;
    [Required]
    [MaxLength(MaxNameLength)]
    public string Name { get; set; }


    public Country()
    {
    }

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

Abaixo a definição do DTO usando uma validação customizada:

Bloco de código
languagec#
firstline1
titleCountryDto.cs
linenumberstrue
public class CountryDto : CustomValidate
{
    public string Name { get; set; }
    public override void AddValidationErrors(CustomValidationContext context)
    {
       if (string.IsNullOrWhiteSpace(Name))
       {
           context.Results.Add(new ValidationResult("Name is required"));
       }
   }
}

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)
        : base(repository)
    {
    }
}

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.

...