Escribir un complemento

Puede crear complementos utilizando uno de los dos siguientes métodos:

  • Las herramientas de desarrollo de Power Platform proporcionan una forma moderna de crear complementos. Las herramientas a las que se hace referencia aquí son Power Platform Tools para Visual Studio y Power Platform CLI. Ambas Power Platform Tools generan un código de complemento similar, por lo que pasar de un método de herramientas a otro es bastante fácil y comprensible.

    • Use las Power Platform Tools para Visual Studio con el fin de crear y registrar (implementar) complementos rápidamente. Está disponible un artículo de inicio rápido que explica cómo se hace. Utilice esta herramienta si le gusta trabajar en Visual Studio.

    • Use Power Platform CLI para crear un proyecto de complemento básico (compatible con Visual Studio) con código de complemento de plantilla utilizando un único comando pac plugin. Luego, usando el comando pac tool prt, utiliza de forma interactiva la herramienta de registro de complementos para registrar su creación con Microsoft Dataverse. Utilice este conjunto de herramientas CLI si le gusta trabajar en una ventana de terminal o en Visual Studio Code.

  • Escriba código manualmente usando su editor favorito o IDE. El resto de la documentación del complemento en este artículo y los otros artículos relacionados se escribe teniendo en cuenta el código de escritura del desarrollador; sin embargo, los conceptos presentados se aplican a todos los métodos de desarrollo de complementos.

Interfaz de IPlugin

Un complemento es una clase compilada dentro de un ensamblado creado para apuntar a .NET Framework 4.6.2. Cada clase en un proyecto de complemento que está registrado en un paso de canalización de eventos debe implementar la interfaz IPlugin, que define un solo método IPlugin.Execute.

public class MyPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        throw new NotImplementedException();
    }
}

El método Execute acepta un único parámetro IServiceProvider. El IServiceProvider tiene un solo método: GetService. Use este método para obtener varios tipos distintos de servicios que puede usar en su código.

Más información: Servicios que puede usar en el código

Importante

Al derivarse de IPlugin, la clase debe escribirse sin estado. Esto se debe a que la plataforma almacena en caché una instancia de clase y la reutiliza por razones de rendimiento. Una forma sencilla de ver esto es que no debe agregar ninguna propiedad ni método a la clase y todo debe estar incluido en el método Execute.

Cuando usa Power Platform Tools para la creación de complementos, la clase PluginBase generada implementa la interfaz IPlugin.

Hay algunas excepciones a la declaración sobre agregar propiedades o métodos en la nota anterior. Por ejemplo puede tener una propiedad que representa una constante y puede tener métodos que se llaman desde el método Execute. Lo importante es que nunca almacene ninguna instancia de servicio o datos de contexto como propiedad en la clase. Estos valores cambian con cada invocación y no conviene que los datos se almacenen en caché y se apliquen a invocaciones posteriores.

Más información: Desarrollar implementaciones de IPlugin como sin estado

Pasar datos de configuración al complemento

Cuando registra un complemento, puede especificar opcionalmente los datos de configuración para pasar al complemento en tiempo de ejecución. Los datos de configuración permiten definir cómo una instancia específica de un complemento registrado debe comportarse. Esta información se pasa como datos de cadena a los parámetros en el constructor de la clase. Hay dos parámetros, es decir, unsecure y secure. Use el primer parámetro unsecure para datos que no le importe que vea alguien más. Use el segundo parámetro secure para datos confidenciales.

El código siguiente muestra las tres firmas de constructor posibles para una clase de complemento llamada MyPlugin.

public MyPlugin() {}
public MyPlugin(string unsecure) {}  
public MyPlugin(string unsecure, string secure) {}

Los datos de configuración seguro se almacenan en una tabla aparte que sólo los administradores del sistema tienen privilegios para leer.

Más información: Registrar paso del complemento > Establecer datos de configuración

Clase abstracta PluginBase

La clase PluginBase implementa la interfaz IPlugin. Ofrecemos esta clase porque implementa un patrón de programación sólido que ha demostrado su eficacia en soluciones comerciales. Sin embargo, el uso de esta clase en el código del complemento es opcional pero recomendado.

La clase no está disponible en ningún ensamblado de SDK, sino que debe generar la clase utilizando una de nuestras herramientas. Para generar la clase, cree un proyecto de complemento en la extensión Power Platform Tools para Visual Studio o ejecute el comando CLI Power Platform pac plugin init. Encontrará un archivo PluginBase.cs en el proyecto generado.

Más información: complemento pac, Inicio rápido: crear un complemento usando Power Platform Tools

Importante

La clase PluginBase generada por la extensión Power Platform Tools y la Power Platform CLI tienen firmas de miembros de clase ligeramente diferentes. Es mejor elegir uno u otro y seguir con él en todo el desarrollo del código del complemento. Ambas versiones de la clase tienen la misma funcionalidad y funcionan de manera similar.

Este diagrama de clases proporciona una visión de las interfaces y clases clave relacionadas con PluginBase.

Clase PluginBase y otros tipos relacionados.

La clase Plugin1 de ejemplo (en el diagrama) deriva de PluginBase. Cambiaría el nombre de esta clase Plugin1 a su propio nombre personalizado y agregaría código para implementar el método ExecuteDataversePlugin y el constructor de clases. La clase LocalPluginContext se inicializa automáticamente con las referencias de servicio indicadas y los puntos finales disponibles para su complemento. Si estuviera implementando la interfaz IPlugin, tendría que escribir código para inicializar todos estos servicios y puntos finales antes de usarlos.

Servicios que puede usar en el código

Normalmente, en el complemento hará lo siguiente:

  • Accederá a los datos contextuales pasados a su complemento para determinar la información sobre la entidad y la solicitud de mensaje que provocó el evento e invocó su complemento. Estos datos se llaman contexto de ejecución.
  • Accederá al servicio web de la organización usando SDK para llamadas .NET para realizar operaciones de solicitud de mensajes como consulta, creación, actualización, eliminación y más.
  • Escribirá mensajes al servicio de seguimiento para poder evaluar cómo se está ejecutando el código del complemento.

Nota

Todos los servicios Dataverse que normalmente usaría su complemento y el contexto de ejecución del complemento están preconfigurados y disponibles para el código de su complemento cuando deriva su complemento de la clase PluginBase.

La propiedad IServiceProvider.GetService le proporciona una forma de acceder a las referencias de servicio pasadas en el contexto de ejecución cuando sea necesario. Para obtener una instancia de un servicio invoque el método GetService que pasa el tipo de servicio. Lea más sobre este método en las secciones siguientes.

Contexto de ejecución

El contexto de ejecución contiene una gran cantidad de información que un complemento puede necesitar. El contexto se obtiene usando el siguiente código.

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

Más información: IPluginExecutionContext, Entender el contexto de ejecución

Servicio web de organización

Además de los datos pasados en el contexto de ejecución, los datos de la fila de la tabla de Dataverse se pueden leer o escribir desde el código del complemento mediante llamadas SDK al servicio web de la organización. No intente utilizar la API web, ya que no es compatible con los complementos. Además, no autentique al usuario antes de acceder a los servicios web, ya que el usuario está preautenticado antes de la ejecución del complemento.

Más información: Operaciones de tabla, Usar mensajes

Para obtener una referencia de objeto al servicio web de la Organización, use el siguiente código:

IOrganizationServiceFactory serviceFactory =
    (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService orgService = serviceFactory.CreateOrganizationService(context.UserId);

Servicio de seguimiento

Use el servicio de seguimiento para escribir mensajes a la tabla PluginTraceLog para poder revisar los registros y comprender qué sucedió cuando se ejecutó el complemento.

Para escribir el registro de seguimientos, debe obtener una instancia del servicio de seguimiento. El siguiente código muestra cómo obtener una instancia del servicio de seguimiento mediante el método IServiceProvider el.GetService Método.

ITracingService tracingService =
    (ITracingService)serviceProvider.GetService(typeof(ITracingService));

Para escribir el seguimiento, use el método ITracingService.Trace Método.

tracingService.Trace("Write {0} {1}.", "your", "message");

Más información: Usar el seguimiento, Seguimiento y registro.

Otros servicios

Cuando escribe un complemento que usa la integración Azure Service Bus, usará un servicio de notificación que implementa la interfaz IServiceEndpointNotificationService, pero esta interfaz no se describirá aquí.

Más información: Integración de Azure

Juntándolo todo

La aplicación de los conceptos de complemento detallados anteriormente da como resultado un código de complemento similar al siguiente.

public class MyPlugin : PluginBase
{
  // Constructor
  public MyPlugin(string unsecureConfiguration, string secureConfiguration)
       : base(typeof(MyPlugin))
  { }

  protected override void ExecuteDataversePlugin(ILocalPluginContext localPluginContext)
  {
    if (localPluginContext == null)
    {
      throw new ArgumentNullException(nameof(localPluginContext));
    }

    var context        = localPluginContext.PluginExecutionContext;
    var serviceFactory = localPluginContext.OrgSvcFactory;
    var tracingService = localPluginContext.TracingService;

    try
    {
      // TODO Plug-in business logic goes here. You can access data in the context,
      // and make calls to the Organization web service using the Dataverse SDK.
    }
    catch (FaultException<OrganizationServiceFault> ex)
    {
      throw new InvalidPluginExecutionException("The following error occurred in MyPlugin.", ex);
    }
    catch (Exception ex)
    {
        tracingService.Trace("MyPlugin: error: {0}", ex.ToString());
        throw;
    }
  }
}

Más información sobre cómo controlar las excepciones: Controlar excepciones en los complementos

El diseño del complemento afecta al rendimiento

Al escribir su complemento, es fundamental que se ejecute de manera eficiente y rápida. El tiempo que tarde en ejecutarse el complemento hace que el usuario final que invocó la operación del mensaje (que activó el complemento) tenga que esperar. Además de procesar la operación del mensaje, Dataverse ejecuta todos los complementos sincrónicos registrados en la canalización, incluido su complemento. Cuando los complementos tardan demasiado en ejecutarse, o si se registran demasiados complementos en una canalización, este impacto en el rendimiento puede provocar que la IU de la aplicación no responda o, en el peor de los casos, un error de tiempo de espera con la reversión de la canalización.

Importante

Los complementos deben cumplir con un límite de tiempo de ejecución y restricciones de recursos. Más información: Analizar el rendimiento del complemento

Uso de tipos enlazados en tiempo de compilación en código de complemento

Puede usar opcionalmente tipos de enlace de tiempo de compilación dentro del código del complemento. Incluya el archivo de tipos generado en el proyecto de complemento. Todos los tipos de tablas proporcionados en la colección de InputParameters del contexto de ejecución son tipos enlazados en tiempo de ejecución. Debería convertir esos tipos enlazados en tiempo de ejecución en tipos enlazados en tiempo de compilación.

Por ejemplo puede realizar las siguientes acciones cuando sabe que el parámetro Target representa una tabla de cuenta. En este ejemplo, "Cuenta" es un tipo enlazado en tiempo de compilación.

Account acct = context.InputParameters["Target"].ToEntity<Account>();

Pero nunca debe intentar establecer el valor con un tipo de compilación. Hacerlo provoca una SerializationException que se produzca.

context.InputParameters["Target"] = new Account() { Name = "MyAccount" }; // WRONG: Do not do this. 

Pasos siguientes

Registrar un complemento
Depuración de complementos

Consulte también

Tutorial: Escribir y registrar un complemento
Administrar excepciones
Prácticas recomendadas e instrucciones sobre la programación de complementos y flujos de trabajo

Nota

¿Puede indicarnos sus preferencias de idioma de documentación? Realice una breve encuesta. (tenga en cuenta que esta encuesta está en inglés)

La encuesta durará unos siete minutos. No se recopilan datos personales (declaración de privacidad).