Plugin to set records' names automatically

On each projects there are entities we can't force user to set names for (because it is needless). However it is good approach if all you records has names, especially if you have to choose these records in lookups.

I use plugins to set names of such entities. To simplify development of such plugins I did a base class and want to share it with you.

Let me show you example of the plugin which is based on SetNamePluginBase (base plugin) I share below.

using ExitoConsulting.Plugins.Base;
using Microsoft.Xrm.Sdk;

namespace ExitoConsulting.Plugins
{
    public class OwnerSetName : SetNamePluginBase
    {
        protected override string GetName(Entity entity, IPluginExecutionContext context, IOrganizationService service)
        {
            var fullName = entity.GetAttributeValue("ec_fullname");
            var clientId = entity.GetAttributeValue("ec_clientid");

            if(string.IsNullOrEmpty(fullName))
            {
                return null;
            }

            var name = fullName;
            if(!string.IsNullOrEmpty(clientId))
            {
                name = name + string.Format(" - {0}", clientId);
            }

            return name;
        }
    }
}


Base class (SetNamePluginBase) I used in example above:
using System;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Metadata;
using Microsoft.Xrm.Sdk.Messages;

namespace ExitoConsulting.Plugins.Base
{
    /// 
    /// Base calass for plugins for setting names of records
    /// 
    public abstract class SetNamePluginBase : IPlugin
    {
        /// 
        /// Entry point. CRM is calling this method as soon as appropriate event take place.
        /// 
        /// 
        public void Execute(IServiceProvider serviceProvider)
        {
            // Getting Plugin Execution Context
            var context = GetContext(serviceProvider);

            // Getting Organization Service
            var service = GetService(serviceProvider);

            // Retrieving current record from the server
            var entity = GetTargetEntity(context, service);

            // Getting primay attribute name (it could be name, subject, topic and so on.)
            var attributeName = GetEntityPrimaryNameAttribute(service, entity.LogicalName);

            if (attributeName == null)
            {
                return;
            }

            // Getting current name of the record
            var oldName = entity.GetAttributeValue(attributeName);

            // Calculating new name for a record
            var name = GetName(entity, context, service);

            if (oldName != name)
            {
                try
                {
                    // Setting new name for a record
                    var toUpdate = GetEmptyEntity(entity);
                    toUpdate.Attributes.Add(attributeName, name);
                    service.Update(toUpdate);
                }
                catch
                {

                }
            }
        }

        /// 
        /// This method have to be overridden in your plugin. The goal is to create a name for provided entity
        /// 
        /// Entity we have to create name for
        /// Plugin execution context
        /// Organization Service
        /// 
        protected abstract string GetName(Entity entity, IPluginExecutionContext context, IOrganizationService service);

        #region Private Methods
        /// 
        /// Returns Organization Service
        /// 
        /// Service Provider
        /// Organization Service
        private IOrganizationService GetService(IServiceProvider serviceProvider)
        {
            var context = GetContext(serviceProvider);
            IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            return factory.CreateOrganizationService(context.UserId);
        }

        /// 
        /// Returns Plugin Execution Context
        /// 
        /// Service Provider
        /// Plugin Execution Context
        private IPluginExecutionContext GetContext(IServiceProvider serviceProvider)
        {
            return (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
        }

        /// 
        /// Returns Target Entity Reference
        /// 
        /// Plugin Execution Context
        /// Target Entity Reference
        private EntityReference GetTargetReference(IPluginExecutionContext context)
        {
            object target = context.InputParameters["Target"];
            if (target is Entity) return ((Entity)target).ToEntityReference();
            if (target is EntityReference) return ((EntityReference)target);

            throw new InvalidPluginExecutionException("Plug-in failed while retrieving target entity reference.");
        }

        /// 
        /// Returns Target Entity
        /// 
        /// Plugin Execution Context
        /// Organization Service
        /// Target Entity
        private Entity GetTargetEntity(IPluginExecutionContext context, IOrganizationService service)
        {
            var targetReference = GetTargetReference(context);
            return service.Retrieve(targetReference.LogicalName, targetReference.Id, new ColumnSet(true));
        }

        /// 
        /// Returns Entity Primary Attribute Name
        /// 
        /// Organization Service
        /// Logical Name of the Entity
        /// Primary Attribute Name
        private string GetEntityPrimaryNameAttribute(IOrganizationService service, string entityName)
        {
            var metadata = GetEntityMetadata(service, entityName);

            if (metadata != null)
            {
                return metadata.PrimaryNameAttribute;
            }

            return null;
        }

        /// 
        /// Returns Entity Metadata
        /// 
        /// Organization Service
        /// Logical Name of the Entity
        /// Entity Metadata
        private EntityMetadata GetEntityMetadata(IOrganizationService service, string entityName)
        {

            var retrieveRequest = new RetrieveEntityRequest
            {
                EntityFilters = EntityFilters.Entity,
                LogicalName = entityName
            };

            // Execute the request.
            var response = (RetrieveEntityResponse)service.Execute(retrieveRequest);

            return response.EntityMetadata;
        }

        /// 
        /// Returns empty entity for update request
        /// 
        /// Entity you want to update
        /// Empty entity created based on provided entity
        private Entity GetEmptyEntity(Entity entity)
        {
            var emptyEntity = new Entity()
            {
                Id = entity.Id,
                LogicalName = entity.LogicalName
            };

            return emptyEntity;
        }

        #endregion
    }
}
You can download Visual Studio project here: