カスタムのトラッキング ビヘイビア (Behavior) の作成と使用


環境: Visual Studio 2010 (.NET Framework 4)

トラッキングのカスタマイズ

こんにちは。

第 1 回 では、カスタムの TrackingParticipant をプログラムコードで作成して利用しました。しかし、実際に Windows Server AppFabric で使用される EtwTrackingParticipant を使用する際は、Web.config に下記の通り定義をおこないます。

<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <etwTracking profileName="Health Tracking"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

そこで今回は、以前 作成した独自な TrackingParticipant (カスタムの TrackingParticipant) を Web.config などの構成ファイル (.config) で使用できるように実装してみましょう。

なお、ここで説明する内容は、WF バージョン 4 の新機能の話はまったくありません。(以前の WCF / WF で利用できる技術をそのまま使うだけです。) ですので、WCF / WF に詳しい方は、もう結論はご存じだと思いますので、以下は読み飛ばしてください。

ここでの実装内容 (概要)

WCF で構成ファイル (.config) に記述されるバインディング (Binding)、ビヘイビア (Behavior) などの各要素は、すべてクラスとして定義されており、このクラスが構成ファイル (Web.config など) で定義されているという単純な構成です。
例えば、バインディング (Binding) の場合は、以前、こちら でも説明したように、バインディングの実装をおこなった Channel などの各クラスと、これを WCF で定義可能にするための BindingElement (バインディング要素) クラスが使用されています。

今回対象とするカスタムの TrackingParticipant は、WCF の内部の動きを操作するものなので、バインディング (Binding) ではなく、ビヘイビア (Behavior) として定義します。
このため、この "振る舞い" そのものを実装した Behavior クラスと、この Behavior を構成ファイル (.config) で要素として定義可能にするための BehaviorElement クラスを作成し、これを .config で使用していきます。

Behavior クラスと BehaviorElement クラスの作成

では、さっそく作成してみましょう。

まず、今回は、コンソールアプリケーションではなく、クラスライブラリのプロジェクトを Visual Studio 2010 で作成します。
さらに、以前 と同様、System.Activities.dll を参照追加し、MyTrackingParticipant クラス (MyTrackingParticipant .cs) を作成します。(このコードは、前回とまったく同じですので省略します!こちら を参照してください。)

つぎに、カスタムの Behavior を作成します。
System.ServiceModel.dll, System.ServiceModel.Activities.dll を参照追加し、クラスを追加して、下記の通り IServiceBehavior インタフェースを実装したカスタムクラスを定義します。

using System.ServiceModel.Description;

class MyTrackingBehavior : IServiceBehavior
{
}

つぎに IServiceBehavior インタフェースを実装します。
実装するメソッドは以下の 3 つですが、今回はこのうち ApplyDispatchBehavior メソッドのみを実装すれば充分です。

class MyTrackingBehavior : IServiceBehavior
{
    public void AddBindingParameters(ServiceDescription serviceDescription,
        System.ServiceModel.ServiceHostBase serviceHostBase,
        System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints,
        System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription,
        System.ServiceModel.ServiceHostBase serviceHostBase)
    {
        throw new NotImplementedException(); // これから実装します。。。
    }

    public void Validate(ServiceDescription serviceDescription,
        System.ServiceModel.ServiceHostBase serviceHostBase){ }
}

つぎに、ApplyDispatchBehavior メソッドとして、前回、Main の処理で記述した内容と同様、ワークフローホスト (もしくは WorkflowInvoker) の Extensions へ MyTrackingParticipant インスタンスの追加をおこないます。
以下の通り実装します。

using System.ServiceModel.Description;
using System.ServiceModel.Activities;
using System.Activities.Tracking;

class MyTrackingBehavior : IServiceBehavior
{
    public void AddBindingParameters(ServiceDescription serviceDescription,
        System.ServiceModel.ServiceHostBase serviceHostBase,
        System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints,
        System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription,
        System.ServiceModel.ServiceHostBase serviceHostBase)
    {
        WorkflowServiceHost workflowHost = serviceHostBase as WorkflowServiceHost;
        TrackingProfile trackingProfile = new TrackingProfile()
        {
            Name = "CustomTrackingProfile",
            Queries = 
            {
                new CustomTrackingQuery() 
                {
                    Name = "*",
                    ActivityName = "*"
                },
                new WorkflowInstanceQuery()
                {
                    States = { WorkflowInstanceStates.Started,
                        WorkflowInstanceStates.Completed },
                },
                new ActivityStateQuery()
                {
                    ActivityName = "*",
                    States = { "*" },
                    Variables = 
                    { { "*" } }
                }
            }
        };
        workflowHost.WorkflowExtensions.Add(()
            => new MyTrackingParticipant
            {
                TrackingProfile = trackingProfile
            });
    }

    public void Validate(ServiceDescription serviceDescription,
        System.ServiceModel.ServiceHostBase serviceHostBase){ }
}

なお、今回は、コードを簡単にするために、上記の通り、TrackingProfile をこのコードの中で作成していますが、TrackingProfile も Web.config の中で指定して、この内容をコードから取得できます。(WebConfigurationManager クラスを使用して取得した Section を System.ServiceModel.Activities.Tracking.Configuration.TrackingSection クラスにキャストすることで、その中に含まれている TrackingProfile クラスを取得できます。)

つづいて、前述の通り、この Behavior を使用した BehaviorElement クラスを作成します。
プロジェクトにクラスを追加し、下記の通り BehaviorExtensionElement から継承された独自のクラスを作成します。

using System.ServiceModel.Configuration;

class MyTrackingExtensionElement : BehaviorExtensionElement
{
    public override Type BehaviorType
    {
        get { return typeof(MyTrackingBehavior); }
    }

    protected override object CreateBehavior()
    {
        return new MyTrackingBehavior();
    }
}

さいごに、この内容を構成ファイル (.config) で使用できるように、System.Configuration.dll への参照追加を忘れずに実施してください。

以上で、必要なクラスの作成 (実装) は完了です。

カスタム Behavior の使用

では、実際に、ワークフローサービスを作成し、Web.config の中で上記を使用してみましょう。

[WCF ワークフローサービスアプリケーション] のプロジェクトを新規追加し (下図)、適当 (任意) にワークフローの処理を作成してみましょう。

このプロジェクトに、上記で作成したプロジェクトを参照追加して、Web.config に下記 (太字) の通り、記述を追加します。

<configuration>
  . . .
  <system.serviceModel>
    <extensions>
      <behaviorExtensions>
        <add name="myTracking" type="ClassLibrary1.MyTrackingExtensionElement, ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </behaviorExtensions>
    </extensions>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          . . .
          <myTracking />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    . . .

ここでは、上記の通り、Web.config に BehaviorExtension を追加していますが、ルートの Web.config などに定義しておくと (この際、あらかじめ、前述のクラスライブラリを署名して、GAC に登録しておく必要があります)、どの WCF サービス (ワークフローサービス) からも、この BehaviorExtension を使用できるようになります。(WCF で使用されている既定の BehaviorExtension のいくつかは、この方法で登録されます。)

クライアントからこのサービスに接続すると、第 1 回 と同じログ (テキストファイル) が出力されるはずです。

ということで、Windows Server AppFabric とは何ら関係ない話に脱線してしまいましたが、.NET 4 から使用可能な etwTracking (Windows Server AppFabric 内で使用) は、
上記のように実装されているのでおぼえておきましょう。(セッションで説明したように、ファイルではなく、ETW へイベントを出力しています。)

 

Comments (0)

Skip to main content