1. Getting an attribute
Before we get an entity's attribute, we always check that the entity first contains the attribute. This is because attempting to access the value of an attribute that doesn't exist throws a NullReferenceException. Here's an example that gets the first name of a contact:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if (contact.Attributes.Contains("firstname")) | |
{ | |
firstName = contact.GetAttributeValue<string>("firstname"); | |
} |
2. Initialising plugin variables
The following code gets the basic objects needed to run a decent plugin. Look how long-winded it is!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Extract the tracing service for use in debugging sandboxed plug-ins. | |
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService)); | |
// Obtain the execution context from the service provider. | |
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); | |
// Obtain the organization service reference. | |
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); | |
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); |
How to shorten things: write extension methods
Create a separate, static class called Extensions.cs. Note the namespace your class is in. If it's in a different namespace to your plugins, you must add a using statement at the top of your plugin classes.Here's an example extension method that allows the simplification of 1. from above:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static T GetValueOrDefault<T>(this Entity entity, string key) | |
{ | |
try | |
{ | |
object value = default(T); | |
if (entity != null && !string.IsNullOrEmpty(key) && entity.Contains(key)) | |
{ | |
value = entity.GetAttributeValue<T>(key); | |
} | |
return (T)value; | |
} | |
catch | |
{ | |
return default(T); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var name = contact.GetValueOrDefault<string>("firstname"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static T GetService<T>(this IServiceProvider serviceProvider) | |
{ | |
return (T)serviceProvider.GetService(typeof(T)); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var tracingService = serviceProvider.GetService<ITracingService>(); | |
var context = serviceProvider.GetService<IPluginExecutionContext>(); | |
var serviceFactory = serviceProvider.GetService<IOrganizationServiceFactory>(); |
I love extension methods too - real time saved.
ReplyDeleteIt's worth noting that you don't need to do the check on GetAttributeValue because it actually does it for you:
private object GetAttributeValue(string attributeLogicalName)
{
if (string.IsNullOrWhiteSpace(attributeLogicalName))
{
throw new ArgumentNullException("attributeLogicalName");
}
if (!this.Contains(attributeLogicalName))
{
return null;
}
return this[attributeLogicalName];
}
Superb, thank you for the feedback Scott! I'll update my post.
Delete