Application Services Design Reference

Keyworks: Elevation Application Service Application Service Provider Dependências Integração IOC Dependency Injection

Conceitos

Application Service

Um application service é uma “façade” para uma funcionalidade da plataforma ou de um módulo e define uma API consistente para a utilizar sem criar dependências exageradas para as classes que a suportam.

Application Service Provider

Um application service provider é uma versão complementar e simplificada de um application service que deve existir apenas quando a funcionalidade em causa da plataforma ou do módulo origem tiver que ser “adaptada” e for implementada por ou comunicar com um módulo externo.

Desenho

Application Services Disponíveis

A lista de application services e de application service providers disponíveis pode ser obtida executando a aplicação com o nível de tracing Verbose ativo. Nesse caso serão registadas mensagens de trace para cada um dos serviços encontrados e registados na aplicação.

Elementos de um Application Service

Um application service deve ser constituído pelos seguintes ficheiros C#:

  • I<AppService>.cs – definição do contrato do serviço.
  • Default<AppService>.cs – definição da implementação do serviço.

No caso dos application service providers será semelhante:

  • I<AppServiceProvider>.cs – definição do contrato do provider.
  • Default<AppServiceProvider>.cs – definição da implementação do provider.

Regras para Desenvolvimento

Devem observar-se as seguintes regras no desenvolvimento dos application services. - O contrato deve ser anotado como atributo [ApplicationService]. - Este atributo permite definir as opções de registo do application service na ObjectFactory. - A classe de implementação deve ser internal e anotada com o atributo [ApplicationServiceImplementation]. - Este atributo define a dependência da implementação para o respetivo contrato. - As dependências para outros application services devem ser criadas no construtor. - Se existir um application service provider correspondente, a dependência para o provider deve ser criada por uma propriedade protected e a sua resolução deve ser efetuada através da classe ApplicationServiceProvider (Primavera.Core.ApplicationServices).

No caso dos application service providers as regras são semelhantes, no entanto, nesse caso, os atributos deverão ser [ApplicationServiceProvider] e [ApplicationServiceProviderImplementation].

Exemplo

Definição do Contrato

/// <summary>
/// Application service to handle user authentication.
/// </summary>
[ApplicationService]
public interface IAuthenticationService
{
    (...)
}

Definição da Implementação

/// <summary>
/// Default implementation for the <see cref="IAuthenticationService"/> application service.
/// </summary>
[ApplicationServiceImplementation(typeof(IAuthenticationService))]
internal class DefaultAuthenticationService : IAuthenticationService
{
    (...)
}

Dependências para Outros Serviços (no Construtor)

/// <summary>
/// Initializes a new instance of the <see cref="DefaultAuthenticationService"/> class.
/// </summary>
/// <param name="requestManagementService">The request management service instance.</param>
/// <param name="identityService">The identity service instance.</param>
public DefaultAuthenticationService(IRequestManagementService requestManagementService, IIdentityService identityService)
{
    (...)
}

Dependências para o Application Service Provider

/// <summary>
/// Gets the underlying provider.
/// </summary>
protected IAuthenticationProvider Provider
{
    get
    {
        if (this.provider == null)
        {
            this.provider = ApplicationServiceProvider.Resolve<IAuthenticationProvider>();
        }

        return this.provider;
    }
}

Registo Automático

No arranque da aplicação a Plataforma tratará de reconhecer todos os application services e application service providers definidos em cada uma das assemblies que fizerem parte da aplicação. Isso torna desnecessário o registo manual desses serviços junto da ObjectFactory e facilita a redução das dependências entre a plataforma e os módulos aplicacionais.

Esse registo acontece nas seguintes condições:

  • Se a implementação do application service estiver anotada com o atributo [ApplicationServiceImplementation] e esse atributo apontar devidamente para o tipo do contrato respetivo.
  • A classe de implementação deve ser internal e deve, naturalmente, implementar o interface do serviço (o contrato).
  • Se o contrato do application service estiver anotado com o atributo [ApplicationService] e se for um interface público.
  • Este último atributo pode, opcionalmente, definir as opções de registo do serviço, correspondentes com as opções da ObjectFactory:
  • RegistrationOption
  • RegistrationLifecycle

É possível diagnosticar este registo automático ativando o nível Verbose do tracing da plataforma.

Resolução

As referências a application services ou application service providers nas classes que pretendam usar as suas funcionalidades deve ser criada através de uma propriedade com a chamada às classes da plataforma responsáveis pela resolução desses tipos: ApplicationService ou ApplicationServiceProvider consoante o caso.

IAuthenticationService authenticationService = ApplicationService.Resolve<IAuthenticationService>();

FAQ

Não consigo resolver o meu novo serviço.

Neste caso, devemos apagar a registration cache para que sejam registados todos os serviços existentes novamente. Este pode ser encontrado em Produto -> Host/App_Data/registration.cache.json.

Nota: este ficheiro encontra-se nos ficheiros ocultos.