Custom Proxy Naming Service.

Beginning in v7, you can now implement your own custom naming service that will be used by XrmToolkit while generating your proxy classes. You must implement one of the following interfaces:

  • Microsoft.Crm.Services.Utility.INamingService - Found in the 'Microsoft.CrmSdk.CoreTools' NuGet package by adding a reference to the 'CrmSvcUtil.exe'.
  • XrmToolkit.ProxyGeneration.Extensions.IProxyNamingService - Found in the 'XrmToolkit.ProxyGeneration.Extensions' NuGet package. Note, this also implements the 'INamingService' interface.
Note:
You must also download and install the XrmToolkit CLI found here: XrmToolkit CLI. You do NOT need a separate license however. The XrmToolkit CLI simply uses the same license that you register upon installing XrmToolkit.

1. Creating the naming service

The most straigt forward approach to supplying your own custom naming service is to create a C# or VB.Net "Library Project" in your solution that will contain the naming service. You could also use an existing library project as well.

After creating the project, install the 'XrmToolkit.ProxyGeneration.Extensions' NuGet package. This package also has a reference to the 'Microsoft.CrmSdk.CoreTools' NuGet package so there is no need to install it separately. By installing this pacakge, it also automatically adds a reference to the 'CrmSvsUtil.exe' file, allowing you to implement the 'INamingService' interface.

2. Choosing which interface to implement

The method that you use for generating your proxy classes will help determine which interface to implement for your custom naming service. If you use the 'CrmSvcUtil' method then implementing the 'Microsoft.Crm.Services.Utility.INamingService' makes the most sense. If you use the 'XrmToolkit' method then you may want to consider implementing the 'XrmToolkit.ProxyGeneration.Extensions.IProxyNamingService'. This interface implements the 'INamingService' interface but also adds some XrmToolkit specific methods like:

  • BeforeProcessEntities - Runs before processing any entities or option sets.
  • BeforeProcessSdkMessagePairs - Runs before processing sdk message pairs.
  • GetNameForBaseProxyClass - Return the name used for the base proxy class.
  • GetNameForRequest - Return the class name for the specified SDK request (custom action).
  • GetNameForResponse - Return the class name for the specified response (custom action).
  • GetNameSpaceForBaseProxyClass - Return the namespace for the base proxy class.
  • GetNameSpaceForEntity - Return the namespace for the specified entity.
  • GetNameSpaceForMessagePair - Return the namespace for the message pair (request/response)
  • GetNameSpaceForOptionSet - Return the namespace for the specified optionset.
  • GetNameSpaceForServiceContext - Return the namespace for the ServiceContext.

3. Implement the interface

Create a class that implements one of the specified interfaces. If you would like to have access to the default name provided by XrmToolkit then your constructor should accept either an 'IProxyNamingService' parameter or 'INamingService' parameter depending on which interface is being implemented.

public class ProxyNamingService : IProxyNamingService
{
    private readonly IProxyNamingService _defaultProxyNamingService;
    public ProxyNamingService(IProxyNamingService defaultProxyNamingService)
    {
        // Get a reference to the default naming service
        this._defaultProxyNamingService = defaultProxyNamingService;
    }

    // IProxyNamingService Implementation
    ...
}

or

public class NamingService : INamingService
{
    private readonly INamingService _defaultNamingService;
    public NamingService(INamingService defaultNamingService)
    {
        // Get a reference to the default naming service
        this._defaultNamingService = defaultNamingService;
    }

    // INamingService Implementation
    ...
}

Then, in your mothed, call the default naming service method and perform any additional actions:

// Prepend the word 'custom_' to the name of the class for an entity
public string GetNameForEntity(EntityMetadata entityMetadata, IServiceProvider services)
{
    var defaultName = this._defaultProxyNamingService.GetNameForEntity(entityMetadata, services);
    if (!defaultName.StartsWith("custom_"))
        defaultName = $"custom_{defaultName}";

    return defaultName;
}
Note:
It is not necessary to write logic for every method. If your service throws a 'NotImplementedException' then the default name generated by XrmToolkit will be used.

4. Set the 'Proxy class naming method'

Update the settings for the solution/project so that the value for the 'Proxy class naming method' is set to one of the following:

  • Custom Naming Service (Project in solution) - You can select a project in the solution where the interface has been implemented.
  • Custom Naming Service (External DLL) - You can browse to the dll where the interface has been implemented.

5. Generate your proxy classes

With the custom naming service specified, you can now generate your proxy classes following the usual flow as specified here.