プラグインを記述する

注意

Effective November 2020:

  • Common Data Service has been renamed to Microsoft Dataverse. Learn more
  • Some terminology in Microsoft Dataverse has been updated. For example, entity is now table and field is now column. Learn more

This article will be updated soon to reflect the latest terminology.

書き込み、登録、およびプラグインをデバッグするプロセスは次のとおりです:

  1. Visual Studio に .NET Framework クラス ライブラリ プロジェクトを作成します。
  2. Microsoft.CrmSdk.CoreAssemblies NuGet パッケージをプロジェクトに追加します。
  3. ステップとして登録されるクラスの IPlugin インターフェイスを実装します。
  4. インターフェイスに必要な Execute メソッドにコードを追加する
    1. 必要なサービスへの参照を取得する
    2. ビジネス ロジックの追加
  5. アセンブリにサインし、ビルドする
  6. アセンブリをテストする
    1. テスト環境でアセンブリを登録する
    2. アンマネージド ソリューションに、登録されたアセンブリとステップを追加する
    3. アセンブリの動作をテストする
    4. 想定されたトレース ログが書き込まれたことを確認する
    5. 必要に応じてアセンブリをデバッグする

このトピックの内容は上記 太字 のステップについて説明し、次のチュートリアルをサポートしています。

アセンブリの制約

作成時には、アセンブリの次の制約に留意してください。

.NET Framework 4.6.2 の使用

プラグインおよびカスタム ワークフロー アセンブリは、.NET Framework 4.6.2を使用する必要があります。 エラーが発生後に 4.6.2 以降に導入された機能を使用する場合、アセンブリが後のバージョンを構築して使用するため一般的には機能します。

アセンブリ開発を最適化する

アセンブリには複数のプラグイン クラス (または種類) を含める必要があるが、16 MB 程度にすることができます。 サイズを 16 MB 未満にする限り、プラグインとワークフロー アセンブリを単一のアセンブリに統合することをお勧めします。 詳細: アセンブリ開発を最適化する

アセンブリには署名が必要である

すべてのアセンブリは登録できるようにするには、サインインする必要があります。 これは、プロジェクトの Visual Studio 署名タブを使用するか、または Sn.exe (Strong Name ツール) を使用して実行できます。

下位の Windows API と対話する .NET アセンブリに依存していでください

プラグインには、それぞれの dll 内にすべての必要なロジックが含まれている必要があります。 プラグインはいくつかのコア .Net アセンブリを参照する場合があります。 とはいえ、グラフィックス デザイン インターフェイスなどの下位の Windows API とやり取りする .Net アセンブリへの依存関係はサポートされていません。

他のアセンブリに依存しないでください

Microsoft.CrmSdk.CoreAssemblies NuGet パッケージを追加すると、これらのアセンブリがアセンブリのビルド フォルダーに含まれますが、ロジックを含むアセンブリとともにこれらのアセンブリをアップロードすることはありません。 これらのアセンブリは、サンドボックス ランタイムにすでに存在します。

プロジェクトのビルド フォルダーに他の NuGet パッケージまたはアセンブリを含めないでください。 アセンブリをロジックに登録するときに、これらのアセンブリを含めることはできません。 Microsoft.CrmSdk.CoreAssemblies NuGet パッケージに含まれているもの以外のアセンブリが存在し、コードと互換性があるとは限りません。

IPlugin インターフェイス

プラグインは、Visual Studio の .NET Framework 4.6.2 を使用する .NET Framework クラス ライブラリ プロジェクトを使用して作成されたアセンブリ内のクラスです。 ステップとして登録されるプロジェクトの各クラスは、IPlugin メソッドが必要な Execute インターフェイスを実装する必要があります。

重要

IPlugin の実装時には、クラスは ステートレス である必要があります。 これは、プラットフォームがクラス インスタンスをキャッシュし、パフォーマンス上の理由から再利用するためです。 これについて考える簡単な方法は、クラスにプロパティまたはメソッドを追加するべきではなく、すべてのものは Execute メソッド内に含める必要があるということです。 これには、いくつかの例外があります。 たとえば、定数を表すプロパティを持つことができる場合には、Execute メソッドから呼び出される関数を表すメソッドを持つことができます。 重要なことは、クラスのプロパティとして、サービス インスタンスやコンテキスト データを格納しないことです。 これらはそれぞれの呼び出しで変わり、そのデータがキャッシュされたり、それ以降の呼び出しに適用されないようにします。 詳細: IPlugin の実装をステートレスとして開発する

Execute メソッドは、単一の IServiceProviderパラメーターを受け取ります。 IServiceProvider には、単一のメソッド: GetService があります。 コードで使用可能な複数の異なる種類のサービスを取得するには、このメソッドを使用します。 詳細: コードで使用可能なサービス

プラグインへの構成データの引き渡し

プラグインを登録するとき、構成データを渡す機能があります。 構成データによって、登録されたプラグインの特定のインスタンスがどのように実行されるかを定義できます。 この情報は、クラスのコンストラクターのパラメーターに文字列データとして渡されます。 2 つのパラメーター: unsecuresecure があります。 最初の unsecure パラメーターはユーザーに表示できでも構わないデータに使用します。 機密データには 2 番目の secure パラメーターを使用します。

次のコードは、SamplePlugin という名前のプラグイン クラスに対する可能な 3 つの署名を示しています。

public SamplePlugin()  
public SamplePlugin(string unsecure)  
public SamplePlugin(string unsecure, string secure)

セキュリティで保護された構成データは、システム管理者のみが読み取り特権がある別のエンティティに格納されます。 詳細: プラグイン登録手順 > 構成データの設定

コードで使用可能なサービス

プラグイン内で必要な事柄:

  • プラグインが処理するために登録された場合、発生する事柄に関するコンテキスト情報にアクセスします。 これは 実行コンテキスト と呼ばれます。
  • データをクエリするためのコードの記述、エンティティ レコードに関する作業、操作を行うためのメッセージの使用を行えるように組織の Web サービスにアクセスします。
  • コードをどのように実行しているかを評価できるように、メッセージをトレース サービス に記述します。

IServiceProvider.GetService メソッドは、必要に応じてこれらのサービスにアクセスする方法を提供します。 サービスのインスタンスを取得するには、サービスの種類を渡す GetService メソッドを呼び出します。

注意

Azure Service Bus 統合を使用してプラグインを記述する場合、IServiceEndpointNotificationService インターフェイスを実装する通知サービスを使用しますが、これはここでは説明されません。 詳細: Azure 統合

組織のサービス

プラグイン内でデータに関する作業をするには、組織サービスを使用します。 Web API は使用しないでください。 プラグインは .NET SDK アセンブリの使用に最適化されています。

IOrganizationService インターフェイスを実装する svc 変数にアクセスするには、次のコードを使用します。

// Obtain the organization service reference which you will need for  
// web service calls.  
IOrganizationServiceFactory serviceFactory =
    (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService svc = serviceFactory.CreateOrganizationService(context.UserId);

IOrganizationServiceFactory.CreateOrganizationService(Nullable<Guid>) とともに使用される context.UserId 変数 UserId プロパティは実行コンテキストから取得されますので、この呼び出しが行われるのは、実行コンテキストにアクセスした後です。

詳細:

プラグイン内で事前バインド型を使用できます。 生成された型ファイルのみをプロジェクトに含めます。 実行コンテキストの入力パラメータによって提供されるすべてのエンティティの種類は遅延バインド型であることに留意する必要があります。 事前バインド型にそれらを変換する必要があります。 たとえば、Target パラメーターが取引先企業エンティティを表すことを確認する場合、以下を実行できます。

Account acct = context.InputParameters["Target"].ToEntity<Account>();

ただし、事前バインド型を使用して値を設定しないようにする必要があります。 これを実行しないようにしてください:

context.InputParameters["Target"] = new Account() { Name = "MyAccount" }; // WRONG: Do not do this. 

これは、SerializationException が発生する原因になります。

トレース サービスの使用

プラグインを実行した場合に発生することを把握するためにログを確認できるよう、トレース サービスを使用して PluginTraceLog エンティティ にメッセージを記述します。

トレース ログに記述するには、トレース サービスのインスタンスを取得する必要があります。 次のコードは、IServiceProvider.GetService を使用してトレース サービスのインスタンスを取得する方法を示しています メソッド。

// Obtain the tracing service
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));

トレースに記述するには、ITracingService.Trace を使用します。 メソッド。

tracingService.Trace("Write {0} {1}.", "your", "message");

詳細については、 トレースを使う, ロギングとトレース を参照してください。

パフォーマンスに関する考慮事項

プラグインに関するビジネス ロジックを追加するときには、パフォーマンス全体に及ぶ影響を十分に認識する必要があります。

重要

同期的な手順として登録されるプラグインのビジネス ロジックは完了するまで 2 秒以内です。

時間とリソースの制約

メッセージ操作が完了するまでには、2 分という時間制限があります。 拡張機能で使用できる CPU およびメモリ リソースの容量にも制限があります。 制限を超えた場合、例外がスローされ、操作はキャンセルされます。

時間制限を超えた場合、TimeoutException がスローされます。 いずれかのカスタム拡張が CPU、メモリ、またはハンドルの制限のしきい値を超過するか、何らかの理由で反応しなくなった場合、そのプロセスはプラットフォームによって強制終了されます。 その時点で、そのプロセスで実行中のすべての拡張機能は例外により失敗します。 ただし、拡張機能の次回の実行時には、拡張機能は正常に動作します。

パフォーマンスの監視

プラグインおよびカスタム ワークフローの拡張機能に関するランタイム情報は取得され、PluginTypeStatistic エンティティ に格納されます。 これらのレコードは、カスタム コードの実行後、30 分から 1 時間以内にデータが取り込まれます。 このエンティティは、次のデータ ポイントを提供します。

属性 説明
AverageExecuteTimeInMilliseconds プラグインの種類の平均実行時間 (ミリ秒) です。
CrashContributionPercent クラッシュの原因となったプラグインの種類の割合です。
CrashCount プラグインの種類がクラッシュした回数です。
CrashPercent プラグインの種類のクラッシュ率です。
ExecuteCount プラグインの種類が実行された回数です。
FailureCount プラグインの種類が失敗した回数です。
FailurePercent プラグインの種類の失敗率です。
PluginTypeIdName プラグインの種類の統計を最後に修正したユーザーを表す一意識別子です。
TerminateCpuContributionPercent プラグインの種類が CPU の過剰使用によるワーカー プロセスの終了に影響を与えた割合です。
TerminateHandlesContributionPercent プラグインの種類がハンドルの過剰使用によるワーカー プロセスの終了に影響を与えた割合です。
TerminateMemoryContributionPercent プラグインの種類がメモリの過剰使用によるワーカー プロセスの終了に影響を与えた割合です。
TerminateOtherContributionPercent プラグインの種類が不明な理由によるワーカー プロセスの終了に影響を与えた割合です。

このデータは、Power Platform 管理センターを使用して参照することもできます分析 > Common Data Service > プラグイン を選択します。

次のステップ

プラグインの登録
プラグインのデバッグ

関連項目

ビジネス プロセスを拡張するためのプラグインを記述する
プラグインとワークフロー開発に関するベストプラクティスとガイダンス 例外を処理する
ユーザーを偽装する
チュートリアル: プラグインを書き込み登録する
チュートリアル: プラグインをデバッグする
チュートリアル: プラグインを更新する