Thursday, March 22, 2012

Extending CrmSvcUtil (Filtering the generated classes)

Most people use the CrmSvcUtil  in its native form. But CrmSvcUtil exposes some interfaces to extend its functionality. Here is the list of all the extension interfaces. One of my personal favourite is ICodeWriterFilterService. This interface can control which entity/attribute/relationship etc. would be created by CrmSvcUtil. By default, CrmSvcUtil generates all the entities, attributes and relationships. If you run the CrmSvcUtil for an out of box CRM online organization, it will generate a file of around 5 mb with all the entities and attributes. In reality we need to generate very few entities for our solutions. We do not need all the extra code generated by the utility. The size of the file is even more important when we are writing code for CRM online. In this blog, we are going to learn how to filter the entities generated by the code generation utility.
Here are the steps:
  1. Open up the solution we created in our last blog.
  2. Add a new class file to the project. I named my class file BasicFilteringService.cs. I copied this file from the sdk samples. Here is the code. The code will restrict the code generation utility to generate just the custom entities.
    using System;
    using Microsoft.Crm.Services.Utility;
    using Microsoft.Xrm.Sdk.Metadata;
    namespace CRMExtensions
    {
        /// 
        /// Sample extension for the CrmSvcUtil.exe tool that generates early-bound
        /// classes for custom entities.
        /// 
        public sealed class BasicFilteringService : ICodeWriterFilterService
        {
            public BasicFilteringService(ICodeWriterFilterService defaultService)
            {
                this.DefaultService = defaultService;
            }
    
            private ICodeWriterFilterService DefaultService { get; set; }
    
            bool ICodeWriterFilterService.GenerateAttribute(AttributeMetadata attributeMetadata, IServiceProvider services)
            {
                return this.DefaultService.GenerateAttribute(attributeMetadata, services);
            }
    
            bool ICodeWriterFilterService.GenerateEntity(EntityMetadata entityMetadata, IServiceProvider services)
            {
                if (!entityMetadata.IsCustomEntity.GetValueOrDefault()) { return false; }
                
                return this.DefaultService.GenerateEntity(entityMetadata, services);
            }
    
            bool ICodeWriterFilterService.GenerateOption(OptionMetadata optionMetadata, IServiceProvider services)
            {
                return this.DefaultService.GenerateOption(optionMetadata, services);
            }
    
            bool ICodeWriterFilterService.GenerateOptionSet(OptionSetMetadataBase optionSetMetadata, IServiceProvider services)
            {
                return this.DefaultService.GenerateOptionSet(optionSetMetadata, services);
            }
    
            bool ICodeWriterFilterService.GenerateRelationship(RelationshipMetadataBase relationshipMetadata, EntityMetadata otherEntityMetadata,
            IServiceProvider services)
            {
                return this.DefaultService.GenerateRelationship(relationshipMetadata, otherEntityMetadata, services);
            }
    
            bool ICodeWriterFilterService.GenerateServiceContext(IServiceProvider services)
            {
                return this.DefaultService.GenerateServiceContext(services);
            }
        }
        //
    }
    
  3. Add codewriterfilter parameter to CrmSvcUtil.exe.config file. <add key="codewriterfilter" value="CRMExtensions.BasicFilteringService, CRMExtensions"/>
  4. Press F5 to debug the solution. It will generate a file  with the name specified in “o” or output parameter.
  5. Check the size of the file. It will be very very small as compare to the file generated without codewriterfilter. The size of the file created for default CRM online  organization with codewriterfilter is just 44 kb as compared to 4.7 mb without codewriterfilter.
Note if we replace the following line in BasicFilteringService.cs
if (!entityMetadata.IsCustomEntity.GetValueOrDefault()) { return false; }
with
if (entityMetadata.LogicalName!="account") { return false; }
The utility will generate just account entity. Happy programming.

9 comments:

  1. Brilliant, thanks for the tip Amreek.

    ReplyDelete
  2. Thanks for the feedback buddy.

    ReplyDelete
  3. really helped me! thanks

    ReplyDelete
  4. Really nice. Thanks Amreek. Do you know if this works on the crmsrvutil in 4.0?

    ReplyDelete
  5. Try this tool (https://xrmearlyboundgenerator.codeplex.com/)! It will also limit which Entities are generated, as well as a whole list of other features.

    ReplyDelete
  6. A locked and restricted crypto account but that did not stop me from the recovery of my crypto assets. I was locked out of my wallet, and restricted for reasons they couldn’t explain to me properly. I thought I had lost everything but a friend of mine recommended MorphoHack to me. A team of cyber security experts, crypto recovery specialists and ethical hackers who helped my case. In my situation, I was about to swindled by the crypto holding company, but MorphoHack helped me recover my crypto assets, gained access to my wallet and helped me regained my confidence. I’m truly thankful for their service and I highly recommend them to everyone out there. Contact them directly at Morphohack@cyberservices.com
    Many people are afraid to pursue it further once they lose access to their crypto wallet and assets, but I put it to you that the longer you wait, the more complicated it becomes. Morphohack can help you act faster and more efficiently, you will be glad that you stumbled upon their services.

    ReplyDelete