Share via


Action Coordination Extensibility

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies.
This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

The default behavior of action execution is that actions are called in the sequence in which they are defined in the Guidance Package configuration file. This behavior can be changed by replacing Recipe Framework action execution and coordination services with custom services. Recipe Framework has two services that collaborate to execute actions of a recipe:

  • Action Execution Service. This service calls actions, keeps a stack of executed actions, and performs a rollback by calling Undo on executed action, if an exception is thrown.
  • Action Coordination Service. This service iterates over the defined actions and executes all of them sequentially.

The services implementations provided with the Recipe Framework can be replaced by custom implementations that can change the default action execution behavior. These custom implementations can be specified as attributes of the <Actions …> element of the Guidance Package configuration file as show here.

<Actions CoordinatorServiceType="... service type ..." ExecutionServiceType="... service type ...">
  <Action ... /> 
  ...
  <... any info for the coordinator service ... >
</Actions>

The <Actions …> configuration element can contain an arbitrary (<any>) configuration element that will be passed directly to the coordination service. For example, this element may contain a script that the coordination service executes.

Both service implementations can be replaced independently; that is, it is not necessary to replace both at the same time. The execution service must implement the IActionExecutionService interface, and the coordination service must implement the IActionCoordinatorService interface.

The IActionCoordinatorService interface is as follows.

public interface IActionCoordinationService
{
  void Run(Dictionary<string, Configuration.Action> declaredActions, XmlElement coordinationData);
}

The Run method receives:

  • A dictionary of recipe action descriptions extracted from the configuration file. The entries in the dictionary are indexed by action names and contain information serialized from respective <Action …> elements.
  • The optional XML element from the <Actions …> element. This parameter can contain arbitrary data used by the coordinator service, and it can be null if no additional information is specified in the configuration file.

Usually, the coordinator determines the actions that need to execute, and then it calls the execution service that implements the following IActionExecutionService interface.

public interface IActionExecutionService
{
  void Execute(string actionName);
  void Execute(string actionName, Dictionary<string, object> inputValues);
}

The second overload of the Execute method allows the coordinator to provide arguments values for the action. The arguments passed in the inputValues dictionary have the exact same behavior and go through the same process as a recipe initial or saved state, or as its argument values. However, if you provide a value for an argument that is also collected by the recipe, the provided value will override the collected value.

You can implement complex action behavior patterns by combining the two extension points.

See also

Developing Actions | Writing Action Classes | Raising Exceptions