Plug-ins 101: Simplifying plug-in development – part 3

A short update of the progress I’m making…

At the moment I’m working on an abstraction layer to ease up the coding of plugins. Right now there are some hard nuts to crack.

Quiz_nutcracker

What have I done till now?

I implemented a base class that has a friendly set of virtual functions that you can override in your plugin class. Instead of having to work with message names and stages, you simply can call the function you need. The wiring on the background is done.

A typical plugin would look like this: lean and mean!

 

[code language=”javascript”]namespace JourneyIntoCRM.PluginBase
{
class TestPlugin: PluginBase
{
public override void OnPreCreate(IPluginExecutionContext context, IOrganizationService service)
{

}
}
}
[/code]

The idea is to have a set of virtual functions that you can override in your plugins. For now I’m planning to support the following functions:

[code language=”javascript”]public virtual void OnValidateCreate(IPluginExecutionContext context, IOrganizationService service) {}
public virtual void OnPreCreate(IPluginExecutionContext context, IOrganizationService service) {}
public virtual void OnPostCreate(IPluginExecutionContext context, IOrganizationService service) {}

public virtual void OnValidateUpdate(IPluginExecutionContext context, IOrganizationService service) { }
public virtual void OnPreUpdate(IPluginExecutionContext context, IOrganizationService service) { }
public virtual void OnPostUpdate(IPluginExecutionContext context, IOrganizationService service) { }

public virtual void OnValidateDelete(IPluginExecutionContext context, IOrganizationService service) { }
public virtual void OnPreDelete(IPluginExecutionContext context, IOrganizationService service) { }
public virtual void OnPostDelete(IPluginExecutionContext context, IOrganizationService service) { }

public virtual void OnPreRetrieve(IPluginExecutionContext context, IOrganizationService service) { }
public virtual void OnPostRetrieve(IPluginExecutionContext context, IOrganizationService service) { }

public virtual void OnPreRetrieveMultiple(IPluginExecutionContext context, IOrganizationService service) { }
public virtual void OnPostRetrieveMultiple(IPluginExecutionContext context, IOrganizationService service) { }

public virtual void OnValidateSetState(IPluginExecutionContext context, IOrganizationService service) { }
public virtual void OnPreSetState(IPluginExecutionContext context, IOrganizationService service) { }
public virtual void OnPostSetState(IPluginExecutionContext context, IOrganizationService service) { }

public virtual void OnExecute(IPluginExecutionContext context, IOrganizationService service) { }
[/code]

Unfortunately the hardest part has still to come.

I need to tackle a big technical hurdle which is the following:

The plugin registration tool sees my base class instead of my derived class. I need to hammer out some reflection code persuade the plugin registration tool to see my derived classes instead of my base class. Once I solved that puzzle in an elegant and understandable way, the code will be up this blog for download.

Not a task for the faint hearted   But nevertheless it has to be done.

Stay tuned!

4 thoughts on “Plug-ins 101: Simplifying plug-in development – part 3

  1. Steven says:

    You would need to decompile CRM to be sure but i am reasonably confident that CRM will only ever execute something that implements the IPlugin Interface; and this will be the thing the Plugin Registration tool is also looking for.

    When you use the Plugin Registration tool all its doing is setting some flags to tell CRM what stage to execute our implementation of IPlugin; you may be able to fool the Tool but i dont think you will be able to fool CRM.

    I think that the idea of a base class that does all of the monkey work is a great idea; i know the constants are something i constantly need to lookup.

    What do you think about exposing Images ‘HasPreImage’ ‘PreImage’ (could return null by default). Mabye even Typesafe variants ‘PreImageOf’ that converts the image to a Strongly Typed entity.

    And of course Service; Tracing and Metadata Service properties

  2. Hi Bas,

    You probably solve this problem by explicitly adding the IPlugin interface to your derived class. So like this:

    class Tesplugin: PluginBase, IPlugin {

    }

    Grtz. Maarten

  3. Hi Bas,

    Maybe you can take it one step further. My ideal plugin signature, I think your former CRM Partners colleague Henk van Boeijen created something like this (not entirely sure here…), is:

    [PostCreatePlugin(“account”, “contact”)]
    public class MyAccountAndContactPostCreatePlugin {

    public void Execute(IPostCreateContext context){
    // …
    }

    }

    But this would require some reflection Pre or Post Build class transformations based on the […PluginAttribute] (in this case a PostCreatePlugin-attribute), like adding the IPlugin interface and copying this class for the ‘account’ and ‘contact’ entities, filling the Plugin Tuple-stuff etc. Each Plugin should only implement an Execute method which gets a context specific to the Plugin type, in this case an IPostCreateContext. This is done so, for example, an IPreCreateContext doesn’t have a PostImage etc.

    Grtz. Maarten

    • Hi Maarten,

      I have all code in front of my eyes and it is working like a charm (but it is really complex). My goal is to provide a much more simple concept, which is more to the core of CRM (with less extensions).
      Anyway lots of homework to do 🙂 Time for a deep dive

      Bas

Leave a Reply

Your email address will not be published. Required fields are marked *