MS Dynamics CRM provides several web service endpoints. This is one of those endpoints, for organisation service.

One of the greatest benefits using this endpoint is to create a context class derived from CrmOrganizationServiceContext, which works as like DbContext from Entity Framework. The context class can be generated by CrmSvcUtil.exe that is shipped in CRM SDK.

When you directly run the following command in the Command Prompt screen, or put the command in build.bat and run the batch file, one single file defined in the /out parameter is generated:

However, there are problems using the generated file:

  • There are number of entities defined in CRM, but there is only one file generated.
  • Each entity can have tens to hundreds of fields (or properties).
  • Not all entities are necessary for generation.

Due to the reasons stated above, even if a very new CRM instance is used to generate the context file, the size of the file is more than 6.5MB, which is huge. If CRM is customised based on business requirements, more entities and fields are generated, which results in the bigger size of the generated file. It is not desirable. I’m not happy at all.

Fortunately, CrmSvcUtil.exe provides an interface called ICodeWriterFilterService. With this interface, only selected entities are filtered and generated as strongly-typed classes. In addition to this, those filtering entities can be set up in a various type of configuration files such as XML, JSON or YAML. In this post, I’m going to show how to implement ICodeWriterFilterService to filter out entities defined in a configuration file in XML, JSON or YAML.

The complete sample code can be found at this repo.

Implementing ICodeWriterFilterService

Within the CRM SDK or this page, you can find the sample code to generate extension codes. Based on that sample code, a new EntityFilteringService class is created for our purpose:

  • You can find the GenerateEntity() method. It accepts EntityMetadata instance as a parameter and validates its entity name – if it’s valid, create the entity; otherwise ignore it.
  • You can also find IFilterItemCollection interface within the constructor. This creates an instance deserialised from a setup file for entity filtering and validates the entity name.

That’s what the EntityFilteringService only does. Once IFilterItemCollection instance is properly implemented, it just works. Now, let’s create classes implementing that interface.

Implementing IFiterItemCollection

First of all, the IFilterItemCollection interface defines one method, IsValidEntity(entityName).

Then that method is implemented in the FilterItemCollection class.

Please note that this FilterItemCollectionClass has the modifier of abstract. As stated above, the filtering setup file can be any format like XML, JSON or YAML. Therefore any corresponding class should inherit this base class. Let’s move onto implementing concrete classes for each setup file format.

XmlFilterItemCollection

If you are an XML person, setup file might be filter.xml and its structure looks like:

Therefore, read the XML file and deserialise it.

JsonFilterItemCollection

If you prefer JSON, create filter.json like:

And deserialise it.

YamlFilterItemCollection

If YAML is your preference, get filter.yml like:

And deserialise it. YamlDotNet makes your life easier for this operation.

All done! Regardless the setup file is filter.xml, filter.json, or filter.yml you can filter out entities only necessary. So, how to apply it? There’s only one step left. Let’s have a look.

build.bat and CrmSvcUtil.exe.config

Firstly, CrmSvcUtil.exe needs its configuration file, CrmSvcUtil.exe.config. We can add “ node for configuration like:

They can be passed within the command prompt, if you like.

  1. language: To define language to generate proxy file.
  2. out: To define the filename for generation. eg) OrganisationService.cs
  3. serviceContextName: To define service context class inheriting CrmOrganizationServiceContext. eg) OrganisationServiceContext
  4. codeCustomization: To point the assembly for filtering extension.
  5. codeWriterFilter: To point the assembly that contains the actual filtering logic.

Once completed, create build.bat looking like:

Inside the batch file, you can setup the CRM service endpoint URL and namespace for output. Also you can ask the user manually type their username and password. Make sure that the password is NOT masked in this example, which is not secure.

Done! Run the build.bat and you’ll be able to see the OrganisationService.cs file generated. So, how can we apply this generated class? Let’s create a Web API app for test. There is a simple Web API app included in the sample code.

Web API Application

The generated OrganisationService.cs has the OrganisationServiceContext class. As this is a partial class, we can extend this class by implementing a new interface, IOrganisationServiceContext for testing and DI purpose. Of course, you can directly use the contet class without it.

IOrganisationServiceContext

In fact, the CrmOrganizationServiceContext class is very similar to the DbContext class, only IQueryable properties need to be defined in the interface. Then implement it with another partial class of OrganisationServiceContext.

One of the reasons using the interface is to write mocking for test codes. Also it’s good for dependency injection with IoC containers. If you use Autofac, for example, the following code snippet shows how to register dependencies.

Now, all setup. You can use OrganisationServiceContext as if you are using Entity Framework.

The result will look like:

So far, we have implemented and applied CRM organisation service context by filtering selected entities with various types of setup files. With this, CRM integration for other applications will be much easier and faster. CRM 2015 also provides REST-basis Web API. This is still at early stage but yet powerfull so will be discussed in another post sooner or later.

Category:
Application Development and Integration, Communication and Collaboration
Tags:
, , , , ,

Join the conversation! 1 Comment

  1. Thanks for sharing.

Comments are closed.