Tips for building plugins
In my last org I did a lot of work with plugins. Plugins can be a great way to solve a host of business problems within an application especially relating to extensibility and deployment. However there are a bunch of gotchas to be aware of that when not addressed can signficantly impact the performance and debuggability of your application. Recently this topic came up on the forums and I posted my list of lessons learned. I am sharing it here as well in thoughts that it might benefit a few people.
Here’s a few pointers based on plugin experience
1. If possible avoid iterating through all the types in your assembly to find the one’s you want (foreach on Type.GetMethods()).
2. If you are constructing many instances for your plugin classes over and over again, then save ConstructorInfo references and use those to activate rather than just Activator.CreateInstance. This will save on the hit of matching the signature.
3. Load when you need to. If you load all your classes at initialization time this can have a signficant hit. Instead you can load assemblies the first time they are needed. Keep a string dictionary / generic hashtable of what has been loaded. This will be less costly then having to use reflection to see if the assembly is loaded.
4. If you are iterating through many assemblies to search for classes to load, then create a seperate AppDomain to do the searching. Build a list of all the assemblies you’ve found that you need to load, and then unload the AppDomain. Next load the assemblies in your list into your main AppDomain.
5. Look at the inner exception during invocation exceptions. Whenever you get an exception via an invocation the outer exception is a generic TargetInvocationException, look in at the inner exception to find what happened. When constructing your objects, use a try-catch and log the inner exception.
6. USE LOGGING. It’s critical to have a log that you can use to trace the execution while your assemblies are loaded, etc. Set logging at different log-levels so you can turn up or down the detail in production environments.
7. Use Exception handling. Create your own friendly verbose exception wrappers for things like LoadAssemblyException, PluginNotFoundException etc and give contextual meaningful messages when they occur. For example give in the message the pathname of the assembly that you were looking for. The more information the better. Although this is a general practice, it’s really important with plugins.
Check here for more detailed guidelines.