Visual Studio 2008 用 Microsoft Dynamics CRM Plug-in テンプレート

みなさん、こんにちは。

今回は、開発系の情報をお届けします。

CRM で Plug-in の開発を行っている方は既にご存知だと思いますが、Plug-in を開発する際には IPlugin
インターフェースを継承したり、Execute メソッドを用意したりと、いくつかお決まりの手順が存在します。

そこで、Microsoft Dynamics CRM User Experience Team が Visual Studio 2008 用のテンプレートを
作成しました。このチームは過去に Plug-in Registration Tool や、Plug-in Developer Tool などを開発した
実績があるチームです。ご存知だったでしょうか?

私も、検証などでコードを書くことがありますが、そのたびに過去のソースをコピーして流用していました。
しかし、このテンプレートには、以下に示すような項目が既に含まれているため、非常に便利です。

  • Secure 及び Non-Secure 情報を Plug-in へ渡すための、コンストラクタ
  • 適切なパラメータをもった Execute メソッド
  • Web Service プロキシの作成
  • 基本的な SOAP 例外のハンドリング
  • Child Pipeline Plug-in 用の Web Service プロキシ作成カスタムメソッド

では、早速インストール手順を見てみましょう。

1. 次の URL より、テンプレート (MSCRM Plug-in.zip) をダウンロードします。
C# 用テンプレート: https://code.msdn.microsoft.com/crmplugintemplate/Release/ProjectReleases.aspx?ReleaseId=1684
VB.NET 用テンプレート: https://code.msdn.microsoft.com/crmplugintemplate/Release/ProjectReleases.aspx?ReleaseId=1684

2. ダウンロードした zip ファイルを、ユーザードキュメント\Visual Studio 2008\Templates\ProjectTemplates\MSCRM\Visual C# (or Visual Basic) フォルダにコピーします。

3. Visual Studio 2008 を起動して、新規プロジェクトの作成を選択します。

4. プロジェクトタイプで言語を選んで、 MSCRM サブフォルダを選択します。

5. MSCRM Plug-in テンプレートを選択して、プロジェクトを作成します。 

 

6. 作成後、ソリューション エクスプローラ\参照設定より、Microsoft.Crm.Sdk とMicrosoft.Crm.SdkTypeProxy
アセンブリを読み込みなおします。

7. さらにソリューション エクスプローラ\プロジェクトのプロパティより、署名タブを選択し、アセンブリの署名を選び、
新しいキーを作成しておいてください。

以下に、実際の C# のコードを紹介します。

    1: using System;
    2: using System.Collections.Generic;
    3: using Microsoft.Win32;
    4:  
    5: // Microsoft Dynamics CRM namespaces
    6: using Microsoft.Crm.Sdk;
    7: using Microsoft.Crm.SdkTypeProxy;
    8: using Microsoft.Crm.SdkTypeProxy.Metadata;
    9:  
   10: namespace Crm.Plugins
   11: {
   12:     public class MyPlugin : IPlugin
   13:     {
   14:         // Provide configuration information that can be passed to a plug-in at run-time.
   15:         private string _secureInformation;
   16:         private string _unsecureInformation;
   17:  
   18:         // Note: Due to caching, Microsoft Dynamics CRM does not invoke the plug-in 
   19:         // contructor every time the plug-in is executed.
   20:         
   21:         // Related SDK topic: Writing the Plug-in Constructor
   22:         public MyPlugin(string unsecureInfo, string secureInfo)
   23:         {
   24:             _secureInformation   = secureInfo;
   25:             _unsecureInformation = unsecureInfo;
   26:         }
   27:  
   28:         // Related SDK topic: Writing a Plug-in
   29:         public void Execute(IPluginExecutionContext context)
   30:         {
   31:             DynamicEntity entity = null;
   32:  
   33:             // Check if the InputParameters property bag contains a target
   34:             // of the current operation and that target is of type DynamicEntity.
   35:             if (context.InputParameters.Properties.Contains(ParameterName.Target) &&
   36:                context.InputParameters.Properties[ParameterName.Target] is DynamicEntity)
   37:             {
   38:                 // Obtain the target business entity from the input parmameters.
   39:                 entity = (DynamicEntity)context.InputParameters.Properties[ParameterName.Target];
   40:  
   41:                 // TODO Test for an entity type and message supported by your plug-in.
   42:                 // if (entity.Name != EntityName.account.ToString()) { return; }
   43:                 // if (context.MessageName != MessageName.Create.ToString()) { return; }
   44:             }
   45:             else
   46:             {
   47:                 return;
   48:             }
   49:  
   50:             try
   51:             {
   52:                 // Create a Microsoft Dynamics CRM Web service proxy.
   53:                 // TODO Uncomment or comment out the appropriate statement.
   54:  
   55:                 // For a plug-in running in the child pipeline, use this statement.
   56:                 // CrmService crmService = CreateCrmService(context, true);
   57:  
   58:                 // For a plug-in running in the parent pipeline, use this statement.
   59:                 ICrmService crmService = context.CreateCrmService(true);
   60:                                 
   61:                 // TODO Plug-in business logic goes here.
   62:  
   63:             }
   64:             catch (System.Web.Services.Protocols.SoapException ex)
   65:             {
   66:                 throw new InvalidPluginExecutionException( 
   67:                     String.Format("An error occurred in the {0} plug-in.", 
   68:                        this.GetType().ToString()),
   69:                     ex);
   70:             }
   71:         }
   72:  
   73:         #region Private methods
   74:         /// <summary>
   75:         /// Creates a CrmService proxy for plug-ins that execute in the child pipeline.
   76:         /// </summary>
   77:         /// <param name="context">The execution context that was passed to the plug-ins Execute method.</param>
   78:         /// <param name="flag">Set to True to use impersonation.</param>
   79:         /// <returns>A CrmServce instance.</returns>
   80:         private CrmService CreateCrmService(IPluginExecutionContext context, Boolean flag)
   81:         {
   82:             CrmAuthenticationToken authToken = new CrmAuthenticationToken();
   83:             authToken.AuthenticationType = 0;
   84:             authToken.OrganizationName = context.OrganizationName;
   85:  
   86:             // Include support for impersonation.
   87:             if (flag)
   88:                 authToken.CallerId = context.UserId;
   89:             else
   90:                 authToken.CallerId = context.InitiatingUserId;
   91:  
   92:             CrmService service = new CrmService();
   93:             service.CrmAuthenticationTokenValue = authToken;
   94:             service.UseDefaultCredentials = true;
   95:  
   96:              // Include support for infinite loop detection.
   97:             CorrelationToken corToken = new CorrelationToken();
   98:             corToken.CorrelationId = context.CorrelationId;
   99:             corToken.CorrelationUpdatedTime = context.CorrelationUpdatedTime;
  100:             corToken.Depth = context.Depth;
  101:  
  102:             RegistryKey regkey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\MSCRM");
  103:  
  104:             service.Url = String.Concat(regkey.GetValue("ServerUrl").ToString(), "/2007/crmservice.asmx");
  105:             service.CorrelationTokenValue = corToken;
  106:  
  107:             return service;
  108:         }
  109:  
  110:         /// <summary>
  111:         /// Creates a MetadataService proxy for plug-ins that execute in the child pipeline.
  112:         /// </summary>
  113:         /// <param name="context">The execution context that was passed to the plug-ins Execute method.</param>
  114:         /// <param name="flag">Set to True to use impersonation.</param>
  115:         /// <returns>A MetadataServce instance.</returns>
  116:         private MetadataService CreateMetadataService(IPluginExecutionContext context, Boolean flag)
  117:         {
  118:             CrmAuthenticationToken authToken = new CrmAuthenticationToken();
  119:             authToken.AuthenticationType = 0;
  120:             authToken.OrganizationName = context.OrganizationName;
  121:  
  122:             // Include support for impersonation.
  123:             if (flag)
  124:                 authToken.CallerId = context.UserId;
  125:             else
  126:                 authToken.CallerId = context.InitiatingUserId;
  127:  
  128:             MetadataService service = new MetadataService();
  129:             service.CrmAuthenticationTokenValue = authToken;
  130:             service.UseDefaultCredentials = true;
  131:  
  132:             RegistryKey regkey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\MSCRM");
  133:  
  134:             service.Url = String.Concat(regkey.GetValue("ServerUrl").ToString(), "/2007/metadataservice.asmx");
  135:  
  136:             return service;
  137:         }
  138:         #endregion Private Methods
  139:     }
  140: }

既に、独自のテンプレートをお持ちの方も多いとおもいますが、まだの方は是非ご利用ください!

参考情報:
MSDN Code Gallary for CRM
https://code.msdn.microsoft.com/Project/ProjectDirectory.aspx?ProjectSearchText=crm

情報元: Microsoft Dynamics Plug-in Template for Visual Studio
https://blogs.msdn.com/crm/archive/2008/10/27/microsoft-dynamics-crm-plug-in-template-for-visual-studio.aspx

- Dynamics CRM サポート 中村 憲一郎

※ワークフロー用テンプレートも欲しいですね~