Registration of Plugin Steps

Minimum Version: 2.2.0 / 3.2.0

Starting with versions 2.2.0 and 3.2.0 there is a new general purpose method to register plugin steps. This new method makes it easier to allow a wide range of different plugin registrations without passing in 7 or 8 parameters like it used to be done with the previous methods.

_context.RegisterPluginStep<FollowUpPlugin>(new PluginStepDefinition() {
    MessageName = "Create",
    EntityLogicalName = Contact.EntityLogicalName,
    Stage = ProcessingStepStage.Postoperation
});

It supports all the functionality in previous versions plus it adds the ability to register plugin steps using the Entity Logical Name property, as opposed to the previous EntityTypeCode value.

This new approach allows the ability to register plugin steps for late bound entities or those that were not generated with an EntityTypeCode.

This new method is the new way going further to register plugin steps, specially because it’ll be used as the foundation for automatic registration in upcoming versions.

Previous existing methods have been marked as obsolete.

If Stage and Mode are not specified, the plugin registration will run synchronously and in the PostOperation stage.

Please have a look to the release notes for more details.

Minimum Version: 2.1.0

Starting with Version 2.1.0 plugin step registration supports new features. Including the ability to filter attributes, registration of images, and plugin step registration validations.

Plugin Steps need to be registered in order to be exeuted by the pipeline. All plugin step registrations use the RegisterPluginStep() method of an IXrmFakedContext.

This section covers specific use cases of plugin step registrations. Please make sure to check the basics of plugin step registration if you are new to pipeline simulation.

PreValidation

Starting with version 2.1.0, pipeline simulation supports plugins running in the PreValidation stage. Please use the PreValidation stage when registering a plugin if you want it to run in that stage:

_context.RegisterPluginStep<ValidatePipelinePlugin, Contact>("Update", ProcessingStepStage.Prevalidation, ProcessingStepMode.Synchronous);

Filtering attributes

Some plugins will fire only when certain attributes are present in the request. When registering these plugins in the plugin registration tool you would select the subset of attributes that will trigger the plugin execution. You can do the same when registering plugin steps in code.

In order to make a plugin step to fire only when certain attributes are present in the request, use the filteringAttributes parameter as follows:

 _context.RegisterPluginStep<ValidatePipelinePlugin, Account>("Update", ProcessingStepStage.Preoperation, ProcessingStepMode.Synchronous, filteringAttributes: new string[] { "name" });

The above plugin will fire only when the ’name’ attribute of an account record is updated.

You can pass multiple attributes to the registration, in that case, the plugin will fire if any of the attributes is present in the request, for the selected message, stage, and mode.

Plugin Step Images

When registering plugins, you can also use plugin images. Images are like “snapshots” of the entity record before (PreImage) and after (PostImage) the request is executed.

In order to setup these images in your plugin registrations, you can use the registeredImages parameter:

string registeredPreImageName = "PreImage";
PluginImageDefinition preImageDefinition = new PluginImageDefinition(registeredPreImageName, ProcessingStepImageType.PreImage);
_context.RegisterPluginStep<EntityImagesInPluginPipeline>("Update", registeredImages: new PluginImageDefinition[] { preImageDefinition });

When registering the image, you need to at least specify the image name, and the image type.

The image name is the key that will be used by the plugin when it is accessed and it should be the same image name you should use when registering the plugin via plugin registration.

The image type accepts the following values:

  • PreImage: If the image is a preImage, use this option when selecting the Pre-Image option in plugin registration.
  • PostImage: If the image is a PostImage, use this option when selecting the Post-Image optionin plugin registration.
  • Both: If the same image name will be registered as both a PreImage and a PostImage.

Attributes in Plugin Step Images

You can also optionally specify attributes when registering images, in that case, only the subset of attributes used in the registration will be present in the image, mimicking the ability of plugin registration to register an image with some attributes only.

In order to use a subset of attributes in the image, please use the constructor of PluginImageDefinition that accepts a list of attributes:

PluginImageDefinition preImageDefinition = new PluginImageDefinition(registeredPreImageName, 
                                                                    ProcessingStepImageType.PreImage, 
                                                                    new string[] { "name" });

Sequence of Plugin Steps

If more than one plugin need to be registered for the same message, stage, and mode, you can define the order in which they’ll execute by using the Rank parameter.

Here’s an example where FollowupPlugin2 will run after FollowupPlugin.

_context.RegisterPluginStep<FollowupPlugin2>(requestName, stage, mode, rank: 2);
_context.RegisterPluginStep<FollowupPlugin>(requestName, stage, mode, rank: 1);

Plugins with Secure and Unsecure configurations

Minimum Version: 2.3.3 / 3.3.3

Starting with versions 2.3.3 and 3.3.3 the plugin step definition has been extended to support registration of plugins with secure and unsecure configurations in pipeline simulation. Simply pass the secure and unsecure configuration strings to your plugin step definition as follows:

var secureConfig = "Fake Secure Config";
var unsecureConfig = "Fake Unsecure Config";

_context.RegisterPluginStep<ConfigurationPluginPipeline>(new PluginStepDefinition()
{
    EntityLogicalName = Account.EntityLogicalName,
    MessageName = "Create",
    Stage = ProcessingStepStage.Preoperation,
    Mode = ProcessingStepMode.Synchronous,
    Configurations = new PluginStepConfigurations()
    {
        SecureConfig = secureConfig,
        UnsecureConfig = unsecureConfig
    }
});

Plugins with custom instances

Minimum Version: 2.3.3 / 3.3.3

Starting with versions 2.3.3 and 3.3.3 the plugin step definition has been extended to support plugin instances that might have been constructed with your own constructors previously. Simply pass the desired plugin instance in the plugin step definition as follows:

var myPluginInstance = new CustomInstancePluginPipeline("My Injected Value");
            
_context.RegisterPluginStep<CustomInstancePluginPipeline>(new PluginStepDefinition()
{
    EntityLogicalName = Account.EntityLogicalName,
    MessageName = "Create",
    Stage = ProcessingStepStage.Preoperation,
    Mode = ProcessingStepMode.Synchronous,
    PluginInstance = myPluginInstance
});

This would allow, for instance, injecting your own 3rd party external dependencies.

You might want to check the section “2) Injecting dependencies in plugins via a custom constructor” about how to inject external dependencies using your custom constructors on the dependency injection documentation.