次の方法で共有


ワークフロー拡張機能

Microsoft Dataverse で使用されるワークフロー デザイナー内で使用できるオプションを拡張できます。 CodeActivity クラスを拡張するクラスを含むアセンブリを追加して、これらの拡張機能を追加します。 これらの拡張機能は、一般に ワークフロー アセンブリ または ワークフロー アクティビティと呼ばれます。

これらのカスタム拡張機能は、ワークフロー デザイナー、カスタム アクション、ダイアログ内で使用できます (非推奨)。

Important

可能な限り、まず、いくつかの宣言型オプションのいずれかを適用してビジネス ロジックを定義することを検討してください。 詳細については、「 Dataverse でのビジネス ロジックの適用」を参照してください。

宣言型プロセスが要件を満たしていない場合は、ワークフロー拡張機能を使用します。

ワークフロー拡張機能を作成するタイミング

既定のプロセス アクティビティを使用して必要な機能が見つからない場合は、カスタム アクティビティを追加して、ワークフロー、ダイアログ、およびアクション プロセスの作成に使用されるエディターで使用できるようにします。

既定では、これらのプロセスには、次の表に示すように、実行できる一般的な一連のアクティビティが含まれています。

Activity Workflow 目的 Dialog
データのクエリ X
値の割り当て X X
レコードの作成 X X X
レコードの更新 X X X
レコードの割り当て X X X
電子メールの送信 X X X
子ワークフローの開始 X X X
アクションの実行 X X
子ダイアログのリンク X
状態の変更 X X X
ワークフローの停止 X X
ダイアログの停止 X

アクションの 実行 アクティビティを使用して、カスタム アクションまたは コマンド アクションと呼ばれる次のシステム メッセージを実行します。

AddToQueue

AddUserToRecordTeam

RemoveUserFromRecordTeam

SetProcess

SetWordTemplate

Dynamics 365 Sales または Service ソリューションがある場合は、ソリューションに応じて他のコマンド アクションを見つけることができます。

ApplyRoutingRule

CalculateActualValue

CloseOpportunity

GetQuoteProductsFromOpportunity

GetSalesOrderProductsFromOpportunity

LockInvoicePricing

LockSalesOrderPricing

QualifyLead

RemoveUserFromRecordTeam

ResolveIncident

ResolveQuote

Revise

UnlockInvoicePricing

UnlockSalesOrderPricing

詳細については、以下を参照してください:

使用されるテクノロジ

カスタム アクティビティを定義する .NET Framework アクティビティ ライブラリ を使用してビルドされたアセンブリを登録できます。 これらのアクティビティは Web アプリケーション エディター内に表示され、プロセスの実行時に呼び出されます。

カスタム ワークフロー アクティビティでは、抽象 CodeActivity クラスから派生した 1 つ以上のクラスを含む .NET Framework アセンブリを作成する必要があります。 このクラスは、アクティビティの実行時に Dataverse プラットフォームが呼び出す Execute(CodeActivityContext) メソッド を提供します。 アセンブリ内の各クラスは、特定のアクティビティを定義します。

ワークフロー アクティビティでは、プロセス デザイナーに表示される入力パラメーターと出力パラメーターを定義する必要があります。 これらのパラメーターを使用すると、だれかがワークフロー アクティビティにデータを渡し、処理された出力を受け取ることができます。 クラスを記述するときに、これらのパラメーターのプロパティを追加し、 .NET 属性 で注釈を付けて、Dataverse がデザイナー内の任意のパラメーターでカスタム ワークフロー アクティビティを公開するために使用するメタデータを提供します。

カスタム ワークフロー アクティビティ アセンブリを作成する

これらの手順では、Visual Studio を使用してカスタム ワークフロー アクティビティを作成する方法について説明します。 詳細な手順の例については、「 チュートリアル: ワークフロー拡張機能を作成する」を参照してください。

  1. .NET Framework 4.6.2 を対象とするクラス ライブラリ プロジェクトを作成します。

    Important

    新しいバージョンを使用してビルドされたアセンブリは通常は機能しますが、4.6.2 以降に導入された機能を使用するとエラーが発生します。

  2. Microsoft.CrmSdk.Workflow NuGet パッケージをインストールします。

    このパッケージには、 Microsoft.CrmSdk.CoreAssemblies パッケージが 含まれています。

  3. (省略可能)事前バインドされたテーブル クラスを使用する場合は、それらをプロジェクトに含めます。

    詳細については、以下を参照してください:

  4. パブリック クラスを追加します。 クラスの名前は、アクティビティが実行するアクションに対応している必要があります。

  5. 次の using ディレクティブを追加します。

    using System.Activities;
    using Microsoft.Xrm.Sdk;
    using Microsoft.Xrm.Sdk.Workflow;
    
  6. 入力パラメーターまたは出力パラメーターを表すプロパティをクラスに追加します。 .NET 属性を使用して、これらのプロパティをワークフロー プロセス デザイナーに公開するために必要なメタデータを提供します。

    詳細については、「パラメーターの 追加」を参照してください。

  7. クラスを CodeActivity クラス から派生させ、アクティビティが実行する操作を含む Execute(CodeActivityContext) メソッド を実装します。

    詳細については、「 Execute メソッドにコードを追加する」を参照してください

  8. アセンブリに署名します。

  9. アセンブリをビルドします。

  10. プラグイン登録ツールを使用してアセンブリを登録します。 NameプロパティとWorkflowActivityGroupNameプロパティを設定して、ワークフロー デザイナーに表示されるテキストを定義します。

    詳細については、「 アセンブリの登録」を参照してください

  11. ワークフロー、ダイアログ、またはアクション プロセス内から呼び出して、ワークフロー アクティビティをテストします。

  12. (推奨)ソリューションにワークフロー アクティビティを追加します。

パラメーターを追加する

クラスのパラメーターを定義するときは、InArgument<T>、OutArgument<T>、または InOutArgument<T> 型として定義します。 これらの型は、パラメーターを取得または設定するための共通 引数クラス から継承されたメソッドを提供します。 コードでは、 Execute メソッドでこれらのメソッドを使用します。 詳細については、「 Execute メソッドにコードを追加する」を参照してください

カスタム ワークフロー アクティビティで入力パラメーターまたは出力パラメーターを使用する場合は、それらを定義するパブリック クラス プロパティに適切な .NET 属性を追加します。 プロセス デザイナーはこのデータを読み取り、プロセス デザイナーでパラメーターを設定する方法を定義します。

入力パラメーターまたは出力パラメーターとして、次の種類のプロパティを使用できます。

int

入力パラメーターと出力パラメーター

プロセス デザイナーで入力または出力パラメーターに表示するテキストを定義するには、 .NET 属性で次のパターンを使用します。

[Input("Integer input")]
public InArgument<int> IntInput { get; set; }

or

[Output("Integer output")]
public OutArgument<int> IntOutput { get; set; }

クラス内の 1 つのプロパティは、両方の属性を含めることで、入力パラメーターと出力パラメーターの両方にすることができます。

[Input("Int input")]  
[Output("Int output")]  
public InOutArgument<int> IntParameter { get; set; }

必須値

プロセスでワークフロー アクティビティを使用するときに入力パラメーターを必須にするには、 [RequiredArgument] 属性を使用します。

既定値

値を入力パラメーターとして渡すか、値を定義せずに出力パラメーターを設定する場合は、既定値を指定します。 たとえば、次のコードは bool プロパティの既定値を設定します。

[Input("Bool input")]
[Default("True")]
public InArgument<bool> Bool { get; set; }

既定値の形式は、プロパティの種類によって異なります。 例を次の表に示します。

タイプ Example
bool [デフォルト("True")]
DateTime [Default("2004-07-09T02:54:00Z")]
Decimal [Default("23.45")]
Double [Default("23.45")]
Money [Default("23.45")]
EntityReference [Default("3B036E3E-94F9-DE11-B508-00155DBA2902", "アカウント")]
int [Default("23")]
OptionSetValue [Default("3")]
文字列 [Default("string default")]

EntityReference パラメーター

EntityReference パラメーターのプロパティを定義するときは、ReferenceTarget属性を使用します。 この属性は、許可されるテーブルの種類を確立します。 例えば次が挙げられます。

[Input("EntityReference input")]
[Output("EntityReference output")]
[ReferenceTarget("account")]
public InOutArgument<EntityReference> AccountReference { get; set; }

OptionSetValue パラメーター

OptionSetValue パラメーターのプロパティを定義するときは、AttributeTarget属性を使用します。 この属性は、パラメーターの有効な値セットを含むテーブルと列を定義します。 例えば次が挙げられます。

[Input("Account IndustryCode value")]
[AttributeTarget("account", "industrycode")]
[Default("3")]
public InArgument<OptionSetValue> IndustryCode { get; set; }

Execute メソッドにコードを追加する

CodeActivity.Execute(CodeActivityContext) メソッドに含めるロジックによって、ワークフロー アクティビティの動作が定義されます。

Important

ステートレスにするコードを Execute メソッドに記述します。 グローバル変数またはメンバー変数を使用して、ある呼び出しから次の呼び出しにデータを渡さないでください。 パフォーマンスを向上させるために、Dataverse はカスタム ワークフロー アクティビティ インスタンスをキャッシュします。 このキャッシュのため、カスタム ワークフロー アクティビティを呼び出すたびにコンストラクターが呼び出されるわけではありません。 また、複数のシステム スレッドで、カスタム ワークフロー アクティビティを同時に実行できます。 CodeActivityContext パラメーターを使用して Execute メソッドに渡される情報のみを使用します。

Reference パラメーター

クラスに対して定義したパラメーターを参照するには、 Argument.Get または Argument.Set(ActivityContext, Object) メソッドを使用します。 これらのメソッドには、 メソッドに渡される Execute インスタンスが必要です。 次の例は、入力パラメーターの値にアクセスし、出力パラメーターの値を設定する方法を示しています。

using Microsoft.Xrm.Sdk.Workflow;
using System.Activities;

namespace SampleWorkflowActivity
{
  public class IncrementByTen : CodeActivity
  {
    [RequiredArgument]
    [Input("Decimal input")]
    public InArgument<decimal> DecInput { get; set; }

    [Output("Decimal output")]
    public OutArgument<decimal> DecOutput { get; set; }

    protected override void Execute(CodeActivityContext context)
    {
      decimal input = DecInput.Get(context);
      DecOutput.Set(context, input + 10);
    }
  }
}

コンテキスト情報を取得する

コードにコンテキスト情報が必要な場合は、< インターフェイスで IWorkflowContextを使用してアクセスします。 このオブジェクトは、操作のコンテキストを記述する多くの読み取り専用プロパティへのアクセスを提供する IExecutionContext インターフェイスから派生します。 IWorkflowContextは、ワークフロー アセンブリを使用する実行中のワークフローに固有の同様のコンテキスト情報を提供します。

Executeにアクセスするには、IWorkflowContext関数で次のコードを使用します。

protected override void Execute(CodeActivityContext context)
{
 IWorkflowContext workflowContext = context.GetExtension<IWorkflowContext>();
...

Important

コンテキスト情報に基づくロジックの依存関係は含めないでください。 ユーザーがワークフローでカスタム ワークフロー アクティビティを使用する場合は、デザイナー内で関連するすべての入力パラメーターを設定する必要があります。 カスタム アクティビティの出力値または動作は、動作を変更する隠れた要因がないように、常に入力パラメーターによってのみ決定する必要があります。 他のユーザーがデザイナーでカスタム アクティビティを使用する場合、動作は常に予測可能である必要があります。

SDK for .NET を使用する

SDK for .NET を使用してデータ操作を実行する必要がある場合は、< インターフェイスで IOrganizationServiceFactory メソッドを使用してアクセスします。 そこから、 CreateOrganizationService(Nullable<Guid>) メソッドを使用して、データ操作の実行に使用できるサービス プロキシのインスタンスにアクセスします。 IWorkflowContext.InitiatingUserId プロパティを使用して、呼び出し元のプロセスと同じコンテキストで操作を実行する場合に使用するユーザー コンテキストを決定できます。 組織サービスにアクセスするには、 Execute 関数で次のコードを使用します。

protected override void Execute(CodeActivityContext context)
{
 IWorkflowContext workflowContext = context.GetExtension<IWorkflowContext>();
 IOrganizationServiceFactory serviceFactory = context.GetExtension<IOrganizationServiceFactory>();

 // Use the context service to create an instance of IOrganizationService.             
 IOrganizationService service = serviceFactory.CreateOrganizationService(workflowContext.InitiatingUserId);
...

アセンブリを登録する

プラグイン登録ツール (PRT) を使用して、カスタム ワークフロー アクティビティを含むアセンブリを登録します。 このツールは、プラグインの登録に使用するツールと同じです。プラグインとカスタム ワークフロー アクティビティの両方で、アセンブリを登録して環境にアップロードする必要があります。 ただし、カスタム ワークフロー アクティビティの手順は登録しません。

カスタム ワークフロー アクティビティの場合は、次のプロパティを指定して、ワークフロー プロセス デザイナーに表示される内容を制御します。

フィールド Description
Description プロセス デザイナーの UI には表示されませんが、この情報を格納する PluginType テーブルから描画されたデータからドキュメントを生成する場合に便利な場合があります。
FriendlyName プラグインのわかりやすい名前。
Name 表されるメニューの名前。
WorkflowActivityGroupName Dataverse プロセス デザイナーのメイン メニューに追加されたサブメニューの名前。

説明的なプロパティを設定します。

これらの値は、ワークフロー アクティビティをテストするときにアンマネージド ソリューションには表示されません。 ただし、このワークフロー アクティビティを含むマネージド ソリューションをエクスポートすると、これらの値がプロセス デザイナーに表示されます。

ワークフロー アクティビティのデバッグ

カスタム ワークフロー アクティビティを Dataverse にデプロイすると、ローカル デバッグのために再生するプロファイルをキャプチャし、トレース サービスを使用してテーブルに情報を書き込むことができます。

次の例は、トレース サービスを使用してメッセージを書き込む方法を示しています。 Add your message.

protected override void Execute(CodeActivityContext context)
{
//Create the tracing service
ITracingService tracingService = context.GetExtension<ITracingService>();

//Use the tracing service
tracingService.Trace("{0} {1} {2}.", "Add", "your", "message");
...

詳細については、以下を参照してください:

ソリューションへの追加

プラグイン登録ツールを使用してアセンブリを登録する場合は、既定の ソリューションにアセンブリを追加します。 このソリューションを Common Data Service の既定のソリューションと混同しないでください。 既定の ソリューション には、環境に適用されているすべてのアンマネージド カスタマイズが含まれているため、ソリューションを使用してカスタム ワークフロー アクティビティを配布する前に、アンマネージド ソリューションに追加する必要があります。 たとえば、 Common Data Service の既定のソリューション または作成したアンマネージド ソリューションに追加できます。

カスタム ワークフロー アクティビティに対する変更を管理する

カスタム ワークフロー アクティビティのコードを維持する必要があります。 コードの変更には破壊的変更が含まれる可能性があるため、この変更を管理する必要があります。 カスタム ワークフロー アセンブリを更新またはアップグレードするには、さまざまな手順を使用します。

カスタム ワークフロー アクティビティを含むアセンブリを登録すると、アセンブリのバージョンが含まれます。 登録ツールは、アセンブリからのリフレクションを使用してこの情報を抽出します。 バージョン番号は、Visual Studio プロジェクトの AssemblyInfo.cs ファイルを使用して制御できます。

下部に次のようなセクションがあります。

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
//[assembly: AssemblyVersion("1.0.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

このバージョン情報は、新しい機能を含める場合に、展開されたアセンブリに更新プログラムを適用したり、アセンブリをアップグレードしたりできるため、重要です。

カスタム ワークフロー アクティビティ アセンブリを更新する

パブリック クラスまたはメソッドシグネチャに大きな変更を加えずにバグを修正したりコードをリファクタリングしたりした場合は、実行中のすべてのプロセスがアセンブリの新しいバージョンの使用を自動的に開始するようにアセンブリを更新します。

アセンブリを更新するには

  1. 属性のAssemblyInfo.csAssemblyVersionのみを変更します。 たとえば、 1.0.0.0 から 1.0.10.5に変更します。
  2. プラグイン登録ツールを使用してアセンブリを更新します。 詳細については、「 アセンブリを更新する」を参照してください。

カスタム ワークフロー アクティビティ アセンブリをアップグレードする

パラメーターの変更など、パブリック クラスまたはメソッド シグネチャに大きな変更を加えた場合は、元のシグネチャを使用するように定義されている現在実行中のプロセスを中断します。 この場合は、アセンブリをアップグレードする必要があります。 このアクションにより、プロセス デザイナーで適用するバージョンを定義するためのオプションを公開する新しいカスタム ワークフロー アクティビティが作成されます。 このバージョン管理により、このアクティビティを使用する各プロセスを再構成して、新しいアセンブリに含まれる変更に適応できます。 アップグレードされたアセンブリを使用するように元のアセンブリを使用するすべてのプロセスが更新されたら、古いアセンブリの登録を解除できます。

アセンブリをアップグレードするには

  1. 新しいアセンブリの NamePublicKeyToken、および Culture が既存のアセンブリと同じであることを確認します。

  2. 属性のAssemblyInfo.csまたはAssemblyVersionの値を変更します。 たとえば、 1.0.0.0 から 2.0.0.0に変更します。

  3. プラグイン登録ツールを使用して、アセンブリを新しいアセンブリとして登録します。 詳細については、「 アセンブリの登録」を参照してください。

  4. カスタム ワークフロー アクティビティを使用する各プロセスについて、プロセスを非アクティブ化し、カスタム ワークフロー アクティビティを使用するステップを編集します。

    使用するアセンブリの バージョン を選択するために使用できるバージョン セレクターがプロセス デザイナーにあります。

    ワークフロー セットのバージョン。

すべてのプロセスが新しいアセンブリを使用するように変換された場合は、プラグイン登録ツールを使用してアセンブリの登録を解除し、使用できなくなります。 詳細については、「コンポーネントの 登録解除」を参照してください。

操作ガイド

ワークフロー拡張機能のパフォーマンスに関する考慮事項は、通常のプラグインの場合と同じです。詳細については、「 プラグインのパフォーマンスを分析する」を参照してください。

通常のプラグインとは異なり、ワークフロー拡張機能では、特定の手順のためにコードを明示的に登録する機会はありません。 ワークフロー拡張機能のコードを同期的に実行するか非同期的に実行するかを制御することはできません。 同期的に実行されるコードは、アプリケーション ユーザーのエクスペリエンスに直接影響するため、特に注意が必要です。

再利用可能なコンポーネントとして、ワークフローまたはカスタム アクションにワークフロー拡張機能を追加できます。 ワークフローは リアルタイム ワークフローとして構成できます。つまり、同期的に実行されます。 カスタム アクションは常に同期されますが、[ ロールバックを有効にする] を設定しない限り、データベース トランザクションには含まれません。

Important

ワークフロー拡張機能が同期ワークフローまたはカスタム アクションで実行されている場合、コードの実行に費やされた時間はユーザーのエクスペリエンスに直接影響します。 このため、ワークフロー拡張機能を同期的に使用する場合、完了するまでに 2 秒以下にする必要があります。 拡張機能にこれより多くの時間が必要な場合は、この制限事項を文書化し、同期ワークフローまたはカスタム アクションでの拡張機能の使用を推奨しません。

次の点に注意してください。トランザクションに参加する同期ワークフローまたはカスタムアクションでは、ワークフロー拡張機能によってスローされたエラーが、トランザクション全体をロールバックさせる原因となります。 このロールバックは、パフォーマンスに影響を与える可能性がある高価な操作です。

ワークフローが同期的に実行されているかどうかを判断するには、 IWorkflowContext.WorkflowMode プロパティの値を使用します。

リアルタイム ワークフロー ステージ

リアルタイム (同期) ワークフローでワークフロー拡張機能を使用すると、イベント実行パイプラインによって特定のステージで拡張機能が呼び出されます。 次の表に、これらのステージを示します。 詳細については、「 イベント実行パイプライン」を参照してください。

メッセージ 段階
作成 PostOperation
削除 PreOperation
Update PreOperation または
PostOperation

ステージを検出するには、 IWorkflowContext.StageName プロパティの値を使用します。

更新操作では、ワークフロー デザイナーの [前] または [] オプションを使用してステージを構成できます。 詳細については、「 リアルタイム ワークフローの使用」を参照してください。

ワークフロー拡張機能が実行コンテキストで渡されたデータに依存している場合、実行されるステージは、 IWorkflowContext.InputParametersIWorkflowContext.OutputParameters でデータを使用できるかどうかを制御します。

InputParametersOutputParametersに基づくロジックの依存関係は含めないでください。 ワークフロー拡張機能は、構成された 入力パラメーターと出力パラメーター に依存する必要があります。そのため、ワークフロー拡張機能を使用しているユーザーは、何も非表示にすることなく、期待される動作を理解できます。

ワークフロー拡張機能のエンティティ イメージ

ワークフロー拡張機能のエンティティ イメージを構成することはできません。 アセンブリを登録するだけで、ワークフロー アクティビティはワークフローのコンテキストで実行されます。 ワークフロー拡張エンティティ イメージは、事前エンティティ イメージと投稿エンティティ イメージにそれぞれ PreBusinessEntity キー値と PostBusinessEntity 値を使用して使用できます。 詳細については、「 エンティティ イメージ」を参照してください。

こちらも参照ください

プラグインとワークフローの開発に関するベスト プラクティスとガイド
チュートリアル: ワークフロー拡張の作成
サンプル: カスタム ワークフロー活動の作成
サンプル: ユーザー定義ワークフロー活動を使用した次回の誕生日の更新
サンプル: ユーザー定義ワークフロー活動で信用度スコアを計算する