Compartir por


Extensiones de flujo de trabajo

Puede ampliar las opciones disponibles en el diseñador de flujo de trabajo que se usa en Microsoft Dataverse. Estas extensiones se agregan agregando un ensamblado que contiene una clase que extiende la clase CodeActivity . Estas extensiones se denominan normalmente ensamblados de flujo de trabajo o actividades de flujo de trabajo.

Puede usar estas extensiones personalizadas en el diseñador de flujo de trabajo, las acciones personalizadas y los diálogos (en desuso).

Importante

Siempre que sea posible, primero debe considerar la posibilidad de aplicar una de las varias opciones declarativas para definir la lógica de negocios. Más información: Aplicación de lógica de negocios en Dataverse

Use extensiones de flujo de trabajo cuando un proceso declarativo no cumpla sus necesidades.

Cuándo crear una extensión de flujo de trabajo

Si no encuentra la funcionalidad que necesita con las actividades de proceso predeterminadas, puede agregar actividades personalizadas para que estén disponibles en el editor que se usa para crear procesos de flujo de trabajo, diálogo y acción.

De forma predeterminada, estos procesos incluyen un conjunto común de actividades que puede realizar como se muestra en la tabla siguiente:

Activity Flujo de trabajo Acción Dialog
Consultar datos X
Asignar valor X X
Crear registro X X X
Actualizar registro X X X
Asignar registro X X X
Enviar correo X X X
Iniciar flujo de trabajo secundario X X X
Realizar acción X X
Vincular diálogo secundario X
Cambiar estado X X X
Detener flujo de trabajo X X
Detener diálogo X

Puede usar la actividad Realizar acción para ejecutar cualquier acción personalizada o los siguientes mensajes del sistema denominados Acciones de comando:

Acciones Acciones (cont'd) Acciones (cont'd)
AddToQueue AddUserToRecordTeam RemoveUserFromRecordTeam
SetProcess SetWordTemplate

Si tiene soluciones de Dynamics 365 Sales o Service, puede encontrar otras acciones de comando en función de la solución:

Acciones Acciones (cont'd) Acciones (cont'd)
ApplyRoutingRule CalculateActualValue CloseOpportunity
GetQuoteProductsFromOpportunity GetSalesOrderProductsFromOpportunity LockInvoicePricing
LockSalesOrderPricing QualifyLead RemoveUserFromRecordTeam
ResolveIncident ResolveQuote Revisar
UnlockInvoicePricing UnlockSalesOrderPricing

Más información:

Tecnología usada

Puede registrar un ensamblado creado mediante la biblioteca de actividades de .NET Framework que define actividades personalizadas que aparecerán en el editor de aplicaciones web y se invocarán cuando se ejecute el proceso.

Las actividades de flujo de trabajo personalizadas requieren la creación de un ensamblado de .NET Framework que incluya una o varias clases derivadas de la clase CodeActivity abstracta. Esta clase proporciona el método Execute(CodeActivityContext) al que llama la plataforma dataverse cuando se ejecuta la actividad. Cada clase del ensamblado definirá una actividad específica.

Las actividades de flujo de trabajo deben definir parámetros de entrada y salida visibles en el diseñador de procesos y permitir que alguien pase datos a la actividad de flujo de trabajo y reciba la salida procesada. Al escribir la clase, agregará propiedades para estos parámetros y las anotará con atributos de .NET a fin de proporcionar los metadatos que Dataverse empleará para exponer su actividad de flujo de trabajo personalizada junto con cualquier parámetro en el diseñador.

Creación de un ensamblado de actividad de flujo de trabajo personalizado

Estos son los pasos generales que se usan para crear una actividad de flujo de trabajo personalizada mediante Visual Studio. Para obtener un ejemplo paso a paso completo, consulte Tutorial: Creación de una extensión de flujo de trabajo.

  1. Cree un proyecto de biblioteca de clases con .NET Framework 4.6.2 como plataforma de destino.

    Importante

    Aunque los ensamblados creados con versiones posteriores suelen funcionar, si usan alguna característica introducida después de la versión 4.6.2, se producirá un error.

  2. Instale el paquete NuGet Microsoft.CrmSdk.Workflow .

    Este paquete incluye el paquete Microsoft.CrmSdk.CoreAssemblies .

  3. (Opcional) Si desea usar clases de tabla enlazadas tempranas, inclúyalos en el proyecto.

    Más información:

  4. Agregue una clase pública. El nombre de la clase debe corresponder con la acción que debe realizar la actividad.

  5. Agregue las siguientes directivas de uso.

    using System.Activities;
    using Microsoft.Xrm.Sdk;
    using Microsoft.Xrm.Sdk.Workflow;
    
  6. Agregue propiedades a la clase para representar cualquier parámetro de entrada o salida y use atributos de .NET para proporcionar metadatos necesarios para exponer estas propiedades al diseñador de procesos de flujo de trabajo.

    Más información: Adición de parámetros

  7. Haga que la clase derive de la clase CodeActivity e implemente el método Execute(CodeActivityContext) que contiene las operaciones que realizará la actividad.

    Más información: Agregar el código al método Execute

  8. Firmar el ensamblado

  9. Compile el ensamblado.

  10. Registre el ensamblado mediante la herramienta Registro de complementos y establezca las propiedades Name y WorkflowActivityGroupName para definir el texto que será visible en el diseñador de flujo de trabajo.

    Más información: Registrar el ensamblado

  11. Probar la actividad de flujo de trabajo invocándola desde un flujo de trabajo, un diálogo, o en un proceso de acción

  12. (Recomendado) Agregue la tarea de flujo de trabajo a una solución.

Incorporación de parámetros

Al definir parámetros para su clase, debe definirlos como tipos InArgument<T>, OutArgument<T>, o InOutArgument<T>. Estos tipos proporcionan métodos heredados de una clase argument común para obtener o establecer los parámetros. El código usará estos métodos en el método Execute. Más información: Agregar el código al método Execute

Cuando la actividad de flujo de trabajo personalizada usa parámetros de entrada o salida, debe agregar los atributos de .NET adecuados a las propiedades de clase pública que las definen. El diseñador de procesos leerá estos datos para definir cómo se pueden establecer los parámetros en el diseñador de procesos.

Puede usar los siguientes tipos de propiedades como parámetros de entrada o salida:

Propiedades Propiedades (continuación) Propiedades (continuación)
Bool DateTime Decimal
Doble EntityReference int
Money OptionSetValue cadena

Parámetros de entrada y salida

Para definir el texto que se va a mostrar para un parámetro de entrada o salida en el diseñador de procesos, usará el siguiente patrón mediante atributos de .NET.

[Input("Integer input")]
public InArgument<int> IntInput { get; set; }

o bien

[Output("Integer output")]
public OutArgument<int> IntOutput { get; set; }

Una sola propiedad de la clase puede ser un parámetro de entrada y salida mediante la inclusión de ambos atributos:

[Input("Int input")]  
[Output("Int output")]  
public InOutArgument<int> IntParameter { get; set; }

Valores necesarios

Para hacer que un parámetro de entrada sea obligatorio al usar la actividad de flujo de trabajo en un proceso, debe usar el atributo [RequiredArgument].

Valores predeterminados

Cuando no se define un valor pasado como parámetro de entrada o establecido como parámetro de salida, puede especificar un valor predeterminado. Por ejemplo, para establecer el valor predeterminado de una propiedad bool:

[Input("Bool input")]
[Default("True")]
public InArgument<bool> Bool { get; set; }

El formato del valor predeterminado depende del tipo de propiedad. Los ejemplos se encuentran en la tabla siguiente:

Tipo Example
Bool [Default("True")]
DateTime [Default("2004-07-09T02:54:00Z")]
Decimal [Default("23.45")]
Doble [Default("23.45")]
Money [Default("23.45")]
EntityReference [Default("3B036E3E-94F9-DE11-B508-00155DBA2902", "cuenta")]
int [Default("23")]
OptionSetValue [Default("3")]
cadena [Default("string default")]

Parámetros de referenciaDeEntidad

Al definir una propiedad para un EntityReference parámetro, debe usar el ReferenceTarget atributo . Esto establece qué tipo de tabla se permite. Por ejemplo:

[Input("EntityReference input")]
[Output("EntityReference output")]
[ReferenceTarget("account")]
public InOutArgument<EntityReference> AccountReference { get; set; }

Parámetros OptionSetValue

Al definir una propiedad para un OptionSetValue parámetro, debe usar el AttributeTarget atributo . Este atributo define qué tabla y columna contienen el conjunto válido de valores para el parámetro . Por ejemplo:

[Input("Account IndustryCode value")]
[AttributeTarget("account", "industrycode")]
[Default("3")]
public InArgument<OptionSetValue> IndustryCode { get; set; }

Agrega tu código al método Execute

La lógica que se incluye en el método CodeActivity.Execute(CodeActivityContext) define lo que hace la actividad de flujo de trabajo.

Importante

El código del Execute método debe escribirse para que no tenga estado. No se recomienda usar variables globales o miembro para pasar datos de una invocación a la siguiente. Para mejorar el rendimiento, Dataverse almacena en caché instancias de actividad de flujo de trabajo personalizadas. Debido a esto, no se llama al constructor para cada invocación de la actividad de flujo de trabajo personalizada. Además, varios subprocesos del sistema podrían ejecutar la actividad de flujo de trabajo personalizada al mismo tiempo. Solo debe usar la información que se pasa a través del parámetro CodeActivityContext al método Execute.

Parámetros de referencia

Para hacer referencia a los parámetros definidos para su clase, usará los métodos Argument.Get o Argument.Set(ActivityContext, Object), que proporcionan y que requieren la instancia CodeActivityContext que se pasa al método Execute. En el ejemplo siguiente se muestra cómo obtener acceso al valor de un parámetro de entrada y establecer el valor de un parámetro de salida.

using Microsoft.Xrm.Sdk.Workflow;
using System.Activities;

namespace SampleWorkflowActivity
{
  public class IncrementByTen : CodeActivity
  {
    [RequiredArgument]
    [Input("Decimal input")]
    public InArgument<decimal> DecInput { get; set; }

    [Output("Decimal output")]
    public OutArgument<decimal> DecOutput { get; set; }

    protected override void Execute(CodeActivityContext context)
    {
      decimal input = DecInput.Get(context);
      DecOutput.Set(context, input + 10);
    }
  }
}

Obtener información contextual

Cuando el código requiere información contextual, puede acceder a esto mediante el método CodeActivityContext.GetExtension<T> con la IWorkflowContext interfaz . Este objeto se deriva de la IExecutionContext interfaz , que proporciona acceso a muchas propiedades de solo lectura que describen el contexto de la operación. El IWorkflowContext proporciona información contextual similar específica del flujo de trabajo que se ejecuta que usa el ensamblado de flujo de trabajo.

Usa el código siguiente en tu función Execute para acceder a IWorkflowContext.

protected override void Execute(CodeActivityContext context)
{
 IWorkflowContext workflowContext = context.GetExtension<IWorkflowContext>();
...

Importante

No debe incluir ninguna dependencia lógica basada en la información de contexto. Cuando la actividad de flujo de trabajo personalizada se usa en un flujo de trabajo, todos los parámetros de entrada relevantes deben establecerse en el diseñador. El valor de salida o el comportamiento de la actividad personalizada siempre deben determinarse únicamente por los parámetros de entrada para que no haya factores ocultos que cambien el comportamiento. Cuando alguien usa la actividad personalizada en el diseñador, el comportamiento siempre debe ser predecible.

Utilice el SDK para .NET

Cuando necesite realizar operaciones de datos mediante el SDK para .NET, puede acceder a esto mediante el método CodeActivityContext.GetExtension<T> con la IOrganizationServiceFactory interfaz . Desde allí puede usar el CreateOrganizationService(Nullable<Guid>) método para acceder a una instancia del proxy de servicio que puede usar para realizar operaciones de datos. . IWorkflowContextInitiatingUserId se puede usar para determinar el contexto de usuario que se va a usar si desea que la operación se realice en el mismo contexto que el proceso de llamada. Utilice el siguiente código en su función Execute para obtener acceso al servicio de la organización:

protected override void Execute(CodeActivityContext context)
{
 IWorkflowContext workflowContext = context.GetExtension<IWorkflowContext>();
 IOrganizationServiceFactory serviceFactory = context.GetExtension<IOrganizationServiceFactory>();

 // Use the context service to create an instance of IOrganizationService.             
 IOrganizationService service = serviceFactory.CreateOrganizationService(workflowContext.InitiatingUserId);
...

Registrar el ensamblado

Usará la herramienta de registro de complementos (PRT) para registrar ensamblados que contienen actividades personalizadas de flujo de trabajo. Esta es la misma herramienta que se usa para registrar complementos. Para los complementos y las actividades de flujo de trabajo personalizadas, debe registrar el ensamblado, que lo cargará en el entorno. Sin embargo, no se registran los pasos de las actividades personalizadas del flujo de trabajo.

Para las actividades de flujo de trabajo personalizadas, debe especificar las siguientes propiedades para controlar lo que se muestra en el diseñador de procesos de flujo de trabajo.

Campo Description
Description No es visible en la interfaz de usuario del diseñador de procesos, pero puede ser útil al generar documentación a partir de datos extraídos de la tabla PluginType que almacena esta información.
FriendlyName Nombre fácil de usar del complemento.
Name Nombre del menú representado
WorkflowActivityGroupName Nombre del submenú agregado al menú principal del diseñador de procesos de Dataverse.

Establezca propiedades descriptivas.

Nota:

Estos valores no estarán visibles en la solución no administrada al probar la actividad del flujo de trabajo. Sin embargo, al exportar una solución administrada que incluya esta actividad de flujo de trabajo, estos valores estarán visibles en el diseñador de procesos.

Depurar actividades de flujo de trabajo

Con las actividades de flujo de trabajo personalizadas implementadas en Dataverse, puede capturar perfiles para reproducir para la depuración local y usar el servicio de seguimiento para escribir información en una tabla.

En el ejemplo siguiente se muestra el uso del servicio de seguimiento para escribir el mensaje siguiente: Add your message.

protected override void Execute(CodeActivityContext context)
{
//Create the tracing service
ITracingService tracingService = context.GetExtension<ITracingService>();

//Use the tracing service
tracingService.Trace("{0} {1} {2}.", "Add", "your", "message");
...

Más información:

Agregar a la solución

Cuando registra ensamblados usando la herramienta de registro de complementos, se agregarán a la Solución predeterminada, que no debe confundirse con la Solución predeterminada de Common Data Service. Dado que la solución Predeterminada contiene todas las personalizaciones no administradas aplicadas al entorno, para poder distribuir la actividad de flujo de trabajo personalizada mediante una solución, debe agregarla a una solución no administrada. Por ejemplo, puede agregarlo a la Solución Predeterminada de Common Data Service o a cualquier solución no administrada que haya creado.

Administración de cambios en actividades de flujo de trabajo personalizadas

Deberá mantener el código de sus actividades personalizadas de flujo de trabajo. Dado que los cambios de código pueden incluir cambios disruptivos, deberá gestionar este cambio. Usará diferentes pasos para actualizar o mejorar sus ensamblados personalizados de flujo de trabajo.

Al registrar un ensamblado que contiene actividades de flujo de trabajo personalizadas, se incluye la versión del ensamblado. Esta información se extrae mediante la reflexión del ensamblado. Puede controlar el número de versión mediante el AssemblyInfo.cs archivo del proyecto de Visual Studio.

Encontrará una sección en la parte inferior que tiene este aspecto:

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
//[assembly: AssemblyVersion("1.0.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Esta información de versión es importante porque permite aplicar actualizaciones a ensamblados implementados o ensamblados de actualización cuando quiera incluir nuevas funcionalidades.

Actualización de un ensamblado de actividad de flujo de trabajo personalizado

Al realizar cambios para corregir errores o volver a factorizar código que no realice cambios significativos en clases públicas o firmas de método, puede actualizar el ensamblado para que todos los procesos en ejecución empiecen a usar automáticamente la nueva versión del ensamblado.

Para actualizar un ensamblado

  1. Cambie solo los valores número de compilación y revisión del AssemblyInfo.csAssemblyVersion atributo. Por ejemplo, cambie de 1.0.0.0 a 1.0.10.5.
  2. Utiliza la herramienta de registro de complementos para actualizar el ensamblado. Más información: Actualización de un ensamblado

Actualización de un ensamblado de actividad de flujo de trabajo personalizado

Si realiza cambios que incluyen cambios significativos en clases públicas o firmas de método, como cambiar los parámetros, interrumpiría los procesos actualmente en ejecución definidos para usar las firmas originales. En este caso debe cambiar la versión del ensamblado. Esto creará una nueva actividad de flujo de trabajo personalizada que expone las opciones que definen la versión que se va a aplicar en el diseñador de procesos. Esto permite que cada proceso que use esta actividad se vuelva a configurar para adaptarse a los cambios incluidos en el nuevo ensamblado. Una vez actualizados todos los procesos que usan el ensamblado original para usar el ensamblado actualizado, puede anular el registro del ensamblado anterior.

Para actualizar un ensamblado

  1. Asegúrese de que el nuevo ensamblado tiene el mismo Name, PublicKeyTokeny Culture que el ensamblado existente.

  2. Cambie los valores versión principal o versión secundaria en el AssemblyInfo.csAssemblyVersion atributo . Por ejemplo, cambie de 1.0.0.0 a 2.0.0.0.

  3. Use la herramienta Registro de complementos para registrar el ensamblado como un nuevo ensamblado. Más información: Registro de un ensamblado

  4. Para cada proceso que utiliza la actividad de flujo de trabajo personalizada, debe desactivar el proceso y editar los pasos que usan la actividad de flujo de trabajo personalizada.

    Encontrará un selector de versiones en el diseñador de procesos que puede usar para elegir qué versión del ensamblado se debe usar.

    Versión del conjunto de flujo de trabajo.

Cuando todos los procesos se convierten para usar el nuevo ensamblado, puede usar la herramienta Registro de complementos para anular el registro del ensamblado, por lo que ya no estará disponible. Más información: Anular el registro de componentes

Guía de rendimiento

Las consideraciones de rendimiento para las extensiones de flujo de trabajo son las mismas que para los complementos normales. Más información: Análisis del rendimiento del complemento

A diferencia de un complemento ordinario, con las extensiones de flujo de trabajo no tiene la oportunidad de registrar explícitamente el código para un paso específico. Esto significa que no controla si el código de la extensión de flujo de trabajo se ejecutará de forma sincrónica o asincrónica. Se debe tener en cuenta especial el código que se ejecuta sincrónicamente, ya que afectará directamente a la experiencia del usuario de la aplicación.

Como componentes reutilizables, las extensiones de flujo de trabajo se pueden agregar a cualquier flujo de trabajo o acción personalizada. El flujo de trabajo se puede configurar como un flujo de trabajo en tiempo real , lo que significa que se ejecutará de forma sincrónica. Las acciones personalizadas siempre son sincrónicas, pero no participan en una transacción de base de datos a menos que tengan configurado el Permitir reversión.

Importante

Cuando la extensión de flujo de trabajo se usa en un flujo de trabajo sincrónico o una acción personalizada, el tiempo dedicado a ejecutar el código afecta directamente a la experiencia del usuario. Por este motivo, las extensiones de flujo de trabajo no deben requerir más de dos segundos para completarse cuando se usan sincrónicamente. Si la extensión requiere más tiempo que esto, debe documentar esto y desalentar el uso de la extensión en flujos de trabajo sincrónicos o acciones personalizadas.

También debe tener en cuenta que en un flujo de trabajo sincrónico o una acción personalizada que participe en la transacción, los errores lanzados por la extensión de flujos de trabajo producirán que la transacción completa se revierta, lo que representa una operación costosa que puede afectar al rendimiento.

Puede usar el valor de la IWorkflowContextpropiedad .WorkflowMode para determinar si el flujo de trabajo se ejecuta de forma sincrónica.

Fases de flujo de trabajo en tiempo real

Cuando se usa una extensión de flujo de trabajo en un flujo de trabajo en tiempo real (sincrónico), se invocará en las fases de canalización de ejecución de eventos que se muestran en la tabla siguiente. Para obtener más información: Canalización de ejecución de eventos

Message Etapa
Crear PostOperation
Eliminar Preoperación
Actualizar PreOperation o
PostOperation

Puede usar el valor en la propiedad IWorkflowContext.StageName para detectar la fase.

Para la operación De actualización , la fase se puede configurar mediante las opciones Antes o Después en el diseñador de flujo de trabajo. Más información: Uso de flujos de trabajo en tiempo real

Si la extensión de flujos de trabajo depende de los datos pasados en el contexto de ejecución, la fase que ejecuta controlará si los datos están disponibles en IWorkflowContext.InputParameters and IWorkflowContext.OutputParameters.

Nota:

No recomendamos incluir dependencias lógicas basadas en el InputParameters y el OutputParameters. Las extensiones de flujo de trabajo deben depender de los parámetros de entrada y salida configurados para que la persona que use la extensión de flujo de trabajo pueda comprender el comportamiento esperado sin tener nada oculto.

Imágenes de entidad para extensiones de flujo de trabajo

No hay ninguna manera de configurar imágenes de entidad para extensiones de flujo de trabajo, ya que solo se registra el ensamblado y la actividad de flujo de trabajo se ejecuta en el contexto del flujo de trabajo. Para extensiones de flujos de trabajo hay disponibles imágenes de entidad mediante los valores clave PreBusinessEntity y PostBusinessEntity respectivamente para imágenes anteriores y posteriores a la entidad. Más información: Imágenes de entidad

Consulte también

Procedimientos recomendados e instrucciones sobre el desarrollo de complementos y flujos de trabajoTutorial: Creación de una extensión de flujo de trabajo
Ejemplo: crear una actividad de flujo de trabajo personalizada
Ejemplo: Actualización del próximo cumpleaños mediante una actividad de flujo de trabajo personalizada
Ejemplo: Cálculo de una puntuación de crédito con una actividad de flujo de trabajo personalizada