This is a largely subjective question and I do not think there is any one correct answer.
Here is a scenario.
Requirement #1: Document Management System
- When a case gets created, I want some custom functionality happening in a (assume non-SharePoint or requires custom development) Document Management System (DMS)
- When a case type is updated, I want custom functionality in DMS.
- When a case is closed, I want custom functionality in DMS.
- When a case is re-activated, I want custom functionality in DMS.
- When I share a record, I want custom functionality in DMS.
- Each Sharing Access Right, invokes a different functionality...i.e., when Read permissions is given I want a functionality and when Write permissions is given, I want another functionality.
- When I assign a record, I want custom functionality in DMS.
Requirement #2: Case Management
- On create - custom logic
- On update of type - custom logic
- On change of status - custom logic
- ...
- ...
You can design them as two different plugin assemblies, one for Document Management System and other for Case Management. The Document Management System assembly, will contain a plugin for each of the requirements. Similarly, the Case Management will contain a different plugin assembly with a plugin for each of the requirements.
I would generally have one plugin assembly but separate plugin for Create / specific Updates / status change (split them into - one for close and one for reactivated?...or is that taking it too far? :-) ). My plugin folder will look something like this
-Plugins
|--Case Management Plugin
| |--OnCaseCreate.cs
| |--OnCaseTypeUpdate.cs
| |--OnCaseClose.cs
| |--OnCaseReactivated.cs
| |--OnCaseAssigned.cs
|--Document Management Plugin
| |--OnCaseCreateRefreshDMS.cs
| |--OnCaseTypeUpdateRefreshDMS.cs
| |--OnCaseCloseRefreshDMS.cs
| |--OnCaseReactivatedRefreshDMS.cs
| |--OnCaseAssignedRefreshDMS.cs
I haven't listed the other folders (CrmPackage) / and files Entities.cs, but you get the idea.
The general thumb rule (in my opinion, based on how CRM is organized - i.e., within Sales you have Opportunity, Quotes, Orders, Invoices etc., and within Service you have Case, Entitlements etc., ) is to segregate by entity and then by functionality to identify how many plugin assemblies you require. Within the plugin assemblies, I would keep the triggers as isolated as possible. There is little point in combining a Create and Update (yes, there are scenarios when a lot of is just common code) in the same plugin class, only to realize a month later that you need to start writing statements such as
if (localcontext.PluginExecutionContext.MessageName.ToLower() == "create")
{
//Do specific functionality for create
}
else
{
//Do functionality for update
}
//Continue with common functionality.
Instead, just put the common functionality in a Shared Library and call them from within the two plugin (classes).
However, there is always generic functionality, but that should be ideally entity agnostic.
For instance, if you have a requirement to send emails (use workflows!) for when one of these entities is created and set the regarding to that particular record, then create
- one plugin assembly called Common Email Management;
- have one plugin within the assembly called GenericEnitityOnCreateSendEmail.
- Register multiple steps in the same plugin for each of the entity.
Hope that helps.
-Sara