読者です 読者をやめる 読者になる 読者になる

Morning Girl

Windows, C#, .NET, Dynamics CRM etc..

【C#】【Dynamics CRM】PluginのContextについて

Dynamics CRM Pluginは各Messageの処理に関連付けて登録し、処理を実行します。

その実行する際に、実行ContextがPluginにパラメータとして渡ってきます。

Contextには様々な種類のデータが格納されて来ますが、そのContextの概要とContextの中で重要な位置を占めるInput・OutputParameterについて、記載していきたいと思います。

Contextについて

まずContextの抽出方法だけ、書き方を確認したいと思います。

PluginのExecuteメソッドにパラメータとして渡ってくる【IServiceProvider】から、GetServiceで【IPluginExecutionContext】を指定することにより、Contextが取得できます。

        public void Execute(IServiceProvider serviceProvider)
        {
            var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

Contextの内容について

Contextは【IPluginExecutionContext】というクラスで登録されています。

MSDN-IPluginExecutionContextメンバー https://msdn.microsoft.com/ja-jp/library/microsoft.xrm.sdk.ipluginexecutioncontext_members.aspx

Contextには実行したPluginに関する様々な情報が渡ってきますが、個人的に下記3種類に大別されていると思っています。

・実行したエンティティ、メッセージ、ユーザーの情報などのPluginプロパティ系。

・実行した際の処理情報にあたるInput・OutputParameter系。

・実行前後のレコード情報などのPre・PostEntityImageのイメージ系。

InputParameter・OutputParameter概要

今回は一番利用頻度が高いと思われるInput・OutPutParameter系を扱ってみます。

InputとOutputはそれぞれ、Message名前空間一覧における、RequestとResponseに対応するようになっているようです。

例えばCreateの場合、CreateRequestとCreateResponseの一セットになっており、RequestにはEntity型で作成するレコードの情報、Responseには実行結果で帰ってくるGuidの情報がそれぞれ渡ってきます。

MSDN-Microsoft.Xrm.Sdk.Messages 名前空間

https://msdn.microsoft.com/ja-jp/library/microsoft.xrm.sdk.messages.aspx

1つ注意すべき点として、OutputParameterのみ、PostOperationステージでのみ扱うことができます。

Type Pre-Validation Pre-Operation Post-Operation
InputParameter
OutputParameter X X

InputParameter・OutputParameter取得方法

以下のようにCreateMessageにPluginを登録した場合、下記のような形でCreateされるInput情報(例えばFormに入力されていた各種フィールドの情報)をEntity型で取得することができます。

var entity = (Entity)context.InputParameters["Target"];

Createの場合パラメータがTargetですが、RetrieveMlutipleであれば"query"のFetchExpression型(ないしQueryExpression)で渡ってきます。 これはそれぞれのMessageRequestによって違ってきますので、登録したMessageそれぞれでどのパラメータが渡ってくるのか、内容を確認する必要があります。

MSDN-CreateRequest のメンバー

https://msdn.microsoft.com/ja-jp/library/microsoft.xrm.sdk.messages.createrequest_members.aspx

OutputParameterも同様です。今回はCreateのMessageに登録しましたので、Response情報はidになりGuid型で受け取ることができます。

var entity = (Guid)context.OutputParameters["id"];

MSDN-CreateResponse のメンバー

https://msdn.microsoft.com/ja-jp/library/microsoft.xrm.sdk.messages.createresponse_members.aspx

その他の特性

InputParameterは言ってしまえばCRM本体から提供された実行されるべきRequestの情報です。

このRequestの情報をPre-validationないしPre-Operationで書き換えることで、実際に実行される情報を変更することが可能です。

その特性を利用した上でのコードを記述してみました。

以下のコードでは、AccountがCreateされた際にわたってきたRequestの【Name】フィールドの末尾に【Plugin Context】という文字列を追記するものです。

using System;
using Microsoft.Xrm.Sdk;

namespace MyProject.Plugin
{
    public class ChangeAccountName : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            // Context の存在判定処理 & Typeの確認
            if(!context.InputParameters.Contains("Target") || !(context.InputParameters["Target"] is Entity))
                return;

            Entity entity = (Entity)context.InputParameters["Target"];

            if (entity.Contains("name"))
                return;

            // AccountのName情報に文字列を追加
            entity["name"] = entity["name"] + " Plugin Context";
        }
    }
}

f:id:sugimomoto:20150413114641p:plain

これによって、わざわざOrganizationServiceを作成することなく、必要に応じて各種データを書き換えることができます。 (もちろん関連エンティティなどを更新する場合は、OrganizationServiceが必要になるかと思います。)

参考URL

MSDN 入力および出力パラメーター https://msdn.microsoft.com/ja-jp/library/gg309673.aspx#bkmk_inputandoutput