2011-05-16 19 views
6

Al crear un complemento en Microsoft Dynamics CRM 4.0, puede usar lo siguiente para verificar el origen del evento que provocó el inicio del complemento.Cómo evitar el bucle infinito sin ExecutionContext.CallerOrigin en Microsoft Dynamics CRM 2011?

public void Execute(IPluginExecutionContext context) 
    { 
     if (context.CallerOrigin.GetType() == CallerOrigin.WebServiceApi.GetType()) 
     { 
      return; 
     } 
     plugin code here... 
    } 

Esto permitirá comprobar si la acción fue causada por un usuario en un formulario, por un servicio web o un flujo de trabajo, etc ...

que tienen una aplicación de sincronización que crea y actualiza las entidades a través de WCF, y no quiere que el complemento se ejecute cuando esto sucede, solo cuando los usuarios editan entidades (para evitar bucles infinitos en el proceso de sincronización).

IExecutionContext.CallerOrigin se ha quitado de Microsoft Dynamics CRM 2011, así que lo que es la nueva manera de hacer esto?

Estaba pensando que podría haber una manera de configurar IExecutionContext.CorrelationId en las llamadas WCF y luego buscar el Guid específico en el complemento, pero todavía no he tenido suerte con esto.

Respuesta

2

¿Has mirado dentro de IPluginExecutionContext.InputParameters?

La otra opción sería modificar su complemento para que no actualice nada si no hubiera cambios, lo que evitaría la posibilidad del bucle infinito.

+0

que podría tener que no actualizar si el cambio fue iniciado por un usuario especificado, ya que no habrá cambios por parte de la herramienta de sincronización. Estoy tratando de evitar la doble sincronización en lugar del bucle infinito :) ya que puedo detener el ciclo en la herramienta de sincronización – csjohnst

+0

context.InitiatingUserId te da la ID de guía. En mi caso, quiero excluir a un solo usuario del complemento de activación y esto funcionó. – kmria

11

Aunque parece que se ha pedido hace algún tiempo (¡y supongo que el OP ya ha encontrado su solución!) Lo encontré buscando una respuesta similar recientemente. Tomó más investigación para descubrir lo que necesitaba, así que por esta razón lo agregaré aquí también para cualquier otra persona que lo encuentre.

En primer lugar, si lo estás buscando, esta propiedad se ha quedado obsoleta. Supuestamente porque no era confiable, pero había algunas razones por las cuales necesitábamos el CallerOrigin en MSCRM 4.0. Por otro lado, hay formas de evitar esto se convierta en obsoleto demasiado:

Evitar bucles infinitos (más de 2 plugins)

Esta fue la razón por la que estaba buscando el CallerOrigin y cómo me encontré con esta pregunta. Solo quería que el complemento se activara si proviene de un usuario en el formulario, no de otro complemento (es decir, un proceso asyc/servicio web). En mi caso, la distinción de que es "más de 2 complementos" es bastante importante, porque no puedo usar InputParameters para resolver el problema. Mi ejemplo fue similar a la siguiente:

  • Actualización Plugin para "Padre" Entidad. Si el conjunto de opciones llamado "Estado" en la entidad padre se estableció en "Aprobado", posteriormente quise establecer también un estado en todas las entidades secundarias en "Aprobado".

  • Plugin de actualización para Entidad "infantil". Si el conjunto de opciones llamado "Estado" en la entidad hijo se configuró en "aprobado", y todos los demás hijos del mismo padre tienen este conjunto en "Aprobado", también tuve que actualizar el estado en el padre para que fuera aprobado.

Esto causa un bucle infinito si no se protege de él. Tampoco puede usar los parámetros de entrada para resolverlo.Una solución básica es utilizar la comprobación de la profundidad:

context.PluginExecutionContext.Depth 

Si esta es mayor que 1 que ha sido llamado por otro plugin/flujo de trabajo. Nota: Si tiene un flujo de trabajo que desencadena la actualización inicial, es posible que desee tener cuidado con el valor que está buscando.

evitar problemas de sincronización de un cliente sin conexión

se nos ha dado diferentes propiedades para ayudar a distinguir estos. Utilizar estos en su lugar:

context.PluginExecutionContext.IsExecutingOffline 
context.PluginExecutionContext.IsOfflinePlayback 

reaccionar de manera diferente dependiendo de lo que es el origen

Ok, por lo que este es el único escenario en el que realmente necesitamos la CallerOrigin. La única forma en que creo que podrás hacerlo es verificando el tipo de PluginExecutionContext. Sé que es asíncrono es del tipo:

Microsoft.Crm.Asynchronous.AsyncExecutionContext 

y para los plugins que parece ser:

Microsoft.Crm.Extensibility.PipelineExecutionContext 

No está seguro de lo que es cuando se viene de una fuente externa, que por desgracia no tengo ningún código disponible en este momento para probar y resolver esto. Fuera de todo lo que es probable que tenga que comprobar:

PluginExecutionContext.ParentContext 

El único otro método que he encontrado para detectar cuando la actualización de vino de está utilizando una marca personalizada en el formulario. Por lo que podría crear un optionset llamado "OriginOfChange" (o algo similar) con las opciones

  • Formulario de CRM (Javascript onsave)
  • flujo de trabajo
  • Plugin
  • etc.

Entonces lo que sea que actualice la entidad establece este campo durante la actualización. De esta forma, puede verificar los parámetros de entrada cada vez para ver de dónde viene la actualización.

Este último método es muy probablemente el más seguro emplear si es necesario reaccionar de manera diferente dependiendo de la fuente. solución

+2

Esta es la mejor respuesta aquí, aunque técnicamente es incorrecto cuando afirma que si la profundidad es mayor que uno, otro plugin llamará a este complemento. Si un flujo de trabajo hace que un complemento se dispare, que tendría una profundidad de 2, si una serie de flujos de trabajo encadenados hacía que el complemento se disparara, la profundidad sería igual al número de flujos de trabajo encadenados juntos + 1. –

+0

@JosephDuty Gracias por la retroalimentación, excelente punto. Actualizaré la pregunta para reflejar esto. –

+0

Para agregar a los 2 últimos puntos, agregué un poco de detalle adicional alrededor del complemento/flujo de trabajo y la verificación de profundidad. En retrospectiva (¡y un par de años más de experiencia!), Creo que debes tener cuidado cuando usas la verificación de profundidad para este propósito. El último método que sugerí es el mejor (en mi opinión) para usar. Dejé en su lugar el quid de la respuesta original, ya que no creo que deba editarse demasiado. –

3

This del hilo es "Sólo tienes que comprobar la propiedad context.depth, si es mayor que 1 retorno"

Funcionó perfectamente bien para mi actualización de plug-in donde estaba actualizando la entidad dentro de ella, haciendo que el plugin para ser despedido dos veces, pero en la segunda vez, verificó la profundidad y salió.

actualización

Con mucho, el método más seguro es usar el plugin de shared parameters en vez de profundidad sin embargo.Si lo único que se comprueba es la profundidad del complemento, cada vez que otro complemento active otro complemento, no se ejecutará porque su profundidad es 2, aunque es la primera vez que el complemento se activa para el evento de actualización.

+0

Siempre he tenido la impresión de que esto no es confiable en la situación en la que tiene, por ejemplo, un flujo de trabajo o un complemento que actualiza su entidad y desencadena el código. P.ej. si su complemento fue diseñado para agregar new_fieldA a new_fieldB y poblar new_fieldTotal y debería activarse si new_fieldA o new_fieldB cambia, entonces 'Depth' en tiempo de ejecución a través de un cambio de UI es 1. Pensé que si otro complemento o flujo de trabajo cambiara new_fieldA o new_fieldB de ese modo desencadenando su complemento y luego 'Profundidad'> 1. Probablemente debería probar esto, pero hago un comentario aquí en caso de que alguien más ya haya ... :) –

-3

La profundidad es de ejecución, no recurrencia. Puede recibir una Profundidad> 1 la primera vez que se ejecuta su complemento. Piense en ello como un nivel en la línea de ejecución (en realidad es la profundidad de la pila de ejecución), alguien lo obtuvo primero, cuando se pasa la ejecución la profundidad aumenta en 1, por lo que el siguiente en la línea realiza otra operación y antes de pasarla de nuevo a la tubería aumenta +1 profundidad, ahora Dynamics ejecuta su complemento, su profundidad sería 3 (Inicial 1 [+1 | +1]). CRM 2011 en las instalaciones está limitado por defecto a 8 y en línea está limitado a una profundidad de 16.

Por lo tanto, la prevención de recursividad mediante el uso de la Profundidad solo lo ASUME, no puede afirmarlo.

MSDN IExecutionContext.Depth Property

mis 2 centavos, Saludos Eric Arean

+0

Aunque estoy de acuerdo en que usted es técnicamente correcto aquí, su respuesta está fuera de contexto en respecto de la pregunta formulada Si esto fue un comentario en contra de una respuesta anterior, podría haber votado en su lugar. –

Cuestiones relacionadas