Extensibilidade do Dataverse

Concluído

Neste tópico, vamos explorar os pontos de extensibilidade do Dataverse disponíveis para desenvolvedores. A arquitetura do Dataverse apresenta uma arquitetura baseada em mensagem para processamento de solicitações. Cada mensagem de solicitação é processada por meio de um pipeline de eventos que tem pontos de extensão para executar lógica de negócios personalizada implementada por plug-ins. Há muitas mensagens fornecidas prontas para uso e, sempre que uma nova tabela é criada, novas mensagens são adicionadas para dar suporte à tabela. Ao criar uma API personalizada, você também cria uma nova mensagem.

Um conceito fundamental é que, independentemente da forma como os dados são acessados, eles são sempre processados como uma mensagem por meio do pipeline de eventos, e qualquer lógica comercial personalizada é executada. Isso será verdadeiro se você usar a interface de usuário de um aplicativo, ou uma das APIs, ou executar operações administrativas como a importação de dados. Não há uma maneira de modificar dados do Dataverse diretamente que possa ignorar o sistema em execução ou a lógica personalizada registrada.

Uso da API do Dataverse

O Dataverse fornece dois estilos de APIs que os desenvolvedores podem usar para interagir com dados: API Web e Serviço da Organização. A seguir é fornecida uma visão geral de alto nível de cada item:

API Web do Dataverse

A API Web está disponível em um ponto de extremidade RESTful OData v4. Use isso para qualquer linguagem de programação compatível com solicitações HTTP e autenticação usando OAuth 2.0. Encontre mais exemplos.

Serviço Dataverse Organization

O Serviço de Organização é um .NET SDK com assemblies .NET fornecidos pela Microsoft, juntamente com geradores de classes tipados para classes de tabela.

Com o Serviço de Organização de um plug-in do Dataverse, o serviço é instanciado e está disponível para o código do plug-in, sem a necessidade de autenticação. Para obter uma instância da lógica do plug-in, você usaria o serviceProvider que é passado ao plug-in para obter uma instância de alocador de serviço da organização (IOrganizationService). Usando o alocador, você pode obter uma instância do serviço de Organização. A seguir está um exemplo de um plug-in simples que obtém uma instância e a usa para criar uma linha da tabela de contas.

public void Execute(IServiceProvider serviceProvider)
{
    IPluginExecutionContext pluginContext = serviceProvider.Get<IPluginExecutionContext>();
    IOrganizationServiceFactory factory = serviceProvider.Get<IOrganizationServiceFactory>();
    IOrganizationService orgService = serviceProvider.GetOrganizationService(pluginContext.UserId);

    Entity newAccount = new Entity("account");                  
    newAccount["name"] = "Fourth Coffee";
    Guid accountid = orgService.Create(newAccount);
}

Você também pode usar o serviço Organização fora dos plug-ins, por exemplo, em um portal personalizado do ASP.NET, no Azure Functions ou até mesmo em um aplicativo de console. Nesses tipos de aplicativos, você usaria o Serviço Dataverse Organization do ServiceClient, que dá suporte a aplicativos que usam o .NET full framework 4.6.2, 4.7.2, 4.8 e o .NET Core 3.0, 3.1, 5.0, 6.0. A classe ServiceClient implementa a interface IOrganizationService. Além disso, o ServiceClient implementa o IOrganizationServiceAsync2, que também disponibiliza versões assíncronas dos métodos.

O exemplo a seguir obtém uma instância de ServiceClient e cria uma nova linha da tabela de contas.

ServiceClient serviceClient =
    new ServiceClient("Url=https://yourenv.crm.dynamics.com;AuthType=OAuth;AppId=51f81489-12ee-4a9e-aaae-a2591f45987d;RedirectUri=http://localhost ;LoginPrompt=Always");

    Entity newAccount = new Entity("account");                  
    newAccount["name"] = "Fourth Coffee";
    Guid accountid = serviceClient.Create(newAccount);

Mais exemplos de uso do serviço de organização estão disponíveis. Você também pode examinar mais detalhes sobre as cadeias de conexão e as opções disponíveis.

As APIs dão suporte a suas próprias abordagens para a criação de consultas de dados, além de dar suporte ao FetchXML. FetchXML é uma linguagem de consulta proprietária usada no Dataverse. A linguagem FetchXML permite que consultas complexas sejam criadas em tabelas relacionadas e usem operadores e condições específicas do Dataverse. O conector Dataverse do Power Automate também oferece suporte à FetchXML.

Pipeline de eventos

Quando você executa uma ação como criar um registro em um aplicativo ou criar um registro usando a API, uma mensagem de criação é processada pelo Dataverse. A mensagem é processada no pipeline de eventos que fornece um conjunto consistente de estágios pelos quais a mensagem passa. Cada estágio, exceto a operação principal, pode ter um plug-in anexado a ele para executar a lógica personalizada. Os seguintes estágios têm suporte quando uma mensagem começa na parte superior e avança pelos estágios do pipeline:

O diagrama de estágios com suporte quando uma mensagem começa na parte superior e avança pelo pipeline.

Ter uma compreensão sólida de como as mensagens são processadas pode ajudá-lo a compreender os comportamentos, e como e onde melhor implementar a lógica personalizada. Também é essencial compreender o pipeline para reconhecer como os plug-ins e as APIs personalizadas se encaixam. Leia mais sobre os detalhes da estrutura de eventos.

Criar plug-ins

Os plug-ins são classes .NET que implementam uma interface IPlugin fornecida por assemblies do SDK do Dataverse. Essa interface exige que você implemente somente um método chamado Execute. Este é um exemplo de implementação mínima:

    public sealed class MyFirstPlugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
               //Business Logic 
         }
    }

O método Execute tem um parâmetro do tipo IServiceProvider. Essa interface tem um método GetService que pode ser usado para recuperar serviços disponíveis para um plug-in. Estes são exemplos de serviços disponíveis:

  • IPluginExecutionContext: permite acessar a mensagem que está sendo processada e as informações sobre o solicitante.

  • ITracingService: permite que você tenha acesso para gravar no Tracelog para fins de diagnóstico.

  • IOrganizationServiceFactory: concede a você acesso para recuperar um OrganizationService para uso no acesso aos dados do plug-in.

Este é um exemplo de uso do GetService para obter o contexto de execução:

IPluginExecutionContext context = (IPluginExecutionContext)                        serviceProvider.GetService(typeof(IPluginExecutionContext));

Ao usar context.InputParameters, você pode ter acesso à mensagem de origem; context.OutputParameters pode dar acesso ao que está sendo devolvido para o chamador.

Uma boa compreensão do contexto de execução é fundamental para um desenvolvedor de plug-ins. Saiba mais sobre o contexto de execução.

Para que um plug-in seja executado, ele deve ser registrado para execução em uma mensagem específica. Isso pode ser feito usando a Plugin Registration Tool.

APIs personalizadas

As operações no Dataverse são definidas como mensagens. As APIs personalizadas oferecem uma forma de código inicial para definir novas mensagens que podem ser estendidas a serviços Web do Dataverse. Essas mensagens podem ser invocadas, da mesma forma que as mensagens do sistema, mas para executar lógica de negócios personalizada. Por exemplo, se você tiver requisitos específicos para pesquisar um cliente usando uma sequência predefinida de chamadas de API, em vez de cada chamador de API implementar essa sequência, poderá implementar uma API personalizada findcustomer. A API findcustomer implementa agora a lógica necessária para procurar o cliente e retornar os resultados. Isso garante que, em vez de cada aplicativo precisar descobrir como encontrar um cliente e fazê-lo de forma inconsistente, ele poderia chamar a API personalizada que processaria as solicitações de pesquisa da mesma maneira em cada ocasião. Se fossem necessárias alterações, elas precisariam ser implementadas em apenas um lugar.

Para definir uma nova API personalizada, comece criando um registro de API personalizado. Isso pode ser feito no maker portal, por meio de código ou usando soluções do Dataverse. Como parte da criação do registro, você identifica o nome da API personalizada e os parâmetros de solicitação e resposta.

Para implementar a lógica da API personalizada, você cria um plug-in e o registra no estágio principal da operação do pipeline. A implementação da API personalizada é o único cenário no qual um plug-in pode ser registrado no estágio da operação principal. Você verá um exemplo dessa ação mais adiante no exercício.

Após implementada, você poderá usar a mensagem personalizada das APIs do Dataverse, do Power Apps e do Power Automate. A seguir está um exemplo de uso da API personalizada findcustomer de C#.

var req = new OrganizationRequest("fabrikam_findcustomer")
{
    ["CustomerName"] = "Contoso",
    ["CustomerAddress"] = "1 Redmond Way"
};

var resp = serviceClient.Execute(req);

Você também não pode implementar um plug-in e permitir que a API personalizada seja usada para disparar outra automação. Por exemplo, a criação de uma API personalizada contendo dados sobre um evento que ocorreu em outro sistema permitiria que esse sistema chamasse essa API no Dataverse, em que muitos pontos de integração diferentes com o Azure, Web Hooks, o Power Automate ou plug-ins assíncronos na API poderiam iniciar outras automações.