CRM 4.0 FAQ > Plug-ins > Will my plug-in class instance be re-used
The simple answer is yes, it can be re-used by CRM, read on for a more detailed discussion on how this can impact you when you code your plug-in.
In designing and coding plug-ins it’s important to understand the life cycle to avoid problems. The first thing you need to know is that you’re plug-in is completely at the mercy of the platform as it manages instancing of your class to service a request. It will decide when it’s appropriate to create a new instance or re-use an existing one. Specific details on those decisions are not available right now but knowing that an instance of a plug-in can be re-used for processing multiple requests is very important to your design and implementation of the plug-in code. You need to ensure that you design your plug-in to be stateless so that the class can handle multiple requests.
In case you haven’t seen the new simplified model for plug-in development (used to be callout in CRM3) here’s a simple implementation. The key thing to notice about the following example that are required for every plug-in is the implantation of the IPlugin interface and the Execute method. Those two key components are what qualify a class to be a plug-in for the platform.
class SimplePlugIn : IPlugin
{
public void Execute ()
{Do real work here…
}
}
Using this overly simplified plug-in example let’s explore some ways that you can get into trouble.
Using Class Instance Variables
In this scenario you might have a counter or some other value that you want to share with other functions in the class that might be called by the Execute method. The following shows an example of using a class instance variable to store a working value.
class SimplePlugIn : IPlugin
{
private int _myWorkingValue = 0;
public void Execute ()
{
DoStuff();
Do more real work here…
}
private void DoStuff()
{
__myWorkingValue ++;
}
}
The problem you can encounter here is the fact that _ myWorkingValue is only initialized the first time when the class is first instanced. If the class instance is re-used by the system, the value will still be as it was from the last request. Initialization must be done as part of the Execute method to ensure the values are cleared each time.
Using Class Constructor for Initialization
In this scenario we are using the class constructor to initialize the value or other items and intend for them to be reset each time.
class SimplePlugIn : IPlugin
{
private int _myWorkingValue;
public SimplePlugIn()
{
_myWorkingValue = 0;
}
public void Execute ()
{
DoStuff();
Do more real work here…
}
private void DoStuff()
{
__myWorkingValue ++;
}
}
The problem with this is the same as the previous Class Instance Variable in that the constructor is only called the first time the class is re-used by the system. Initialization must be done as part of the Execute method to ensure the values are cleared each time.
Using Class Static Variable
In this scenario we define a class static variable that we want to keep track of how many times the plug-in was invoked.
class SimplePlugIn : IPlugin
{
private static int _myCountInvoked;
public void Execute ()
{
_myCountInvoked++;
Do more real work here…
}
}
There are a couple of problems with this approach. First, it’s possible there are multiple instances of this class running in different threads. In that event we need to provide some thread safety during our update to having problems that are inconsistent and very hard to track down. Second, if we are relying on this count to be accurate we would be wrong since it’s possible to have multiple processes running the plug-in. This can occur under a couple of deployment models of the platform such as a web farm, or running the asynchronous service on multiple back end servers.
So the bottom line is that best practice for plug-in development is to minimize if not eliminate anything that requires your plug-in to maintain state. If you do need to maintain some type of state make sure you are very aware of possible issues that could arise. If for caching reasons or other performance needs you do leverage one time initializations for a class or an instance make sure you take steps to prevent threading issues or other variable reuse problems.
Last updated on October 19, 2007 by David Yack
