眠いしお腹すいたし(´・ω・`)

C#関連を主に書きます。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

Azure Functionsのカスタム出力バインディングの作り方を調べた

Azure Functionsのバインディングの自作方法を調べてみました。

結論から言うと

github.com

このページに全て書いてあります。

ですので、ここからは私の勉強メモということで

github.com

こちらに出力バインディングツイッターでツイートするサンプルを作ってみました。

出力バインディングを指定するパラメータAttributeの作り方

Microsoft.Azure.WebJobs.Description.BindingAttribute が付いたAttributeを作成すればOK。

作成するカスタムAttributeのプロパティにAppSettingAttributeを付けるとプロパティの文字列でConfigurationManager.AppSettingsのキー名で検索を行って値を設定してくれる。接続文字列、ユーザ・パスワードなどのプロパティに設定しておくとよいです。

出力バインディングするためのクラスの作り方

出力バインディングするためのクラスはIAsyncCollectorを実装したクラスを作成するかStreamを実装したクラスを作成します。

今回は簡単なIAsyncCollectorを実装しました。

SampleProjects/TweetAsyncCollector.cs at master · yuka1984/SampleProjects · GitHub

IAsyncCollectorはAddAsyncとFlushAsyncを宣言していますので、この二つの関数を実装する必要があります。

FunctionsにてICollector.Add /IAsyncCollector.AddAsyncが呼ばれた際にAddAsyncが呼び出されます。FunctionsにてICollectorを引数としている場合にはSyncAsyncCollectorAdapterというICollector実装クラスにIAsyncCollector実装がラップされて実行されます。Addが呼び出された時にGetAwaiter.GetResultしてる感じです。

out string みたいな引数のケースでは後程説明しますが関数終了直後にAddAsyncが呼び出されます。 そこまで処理がすべて完了したらFlushAsyncが呼び出される感じです。

この仕組みで重要な点はIAsyncCollectorの実装では必ずしもAddAsync時に出力が行われているわけではなくFlushAsyncが終了した段階でAddAsyncされたデータが出力されていると考える必要があるということです。

ようするにAddAsyncで出力が行われるかは出力バインディングの実装次第だよ、っていうことです。

バインドを行う為の設定クラスの作り方

Attributeを作成したら次はバインド設定を行う為のクラスを作ります。

Microsoft.Azure.WebJobs.Host.Config.IExtensionConfigProviderの実装クラスを作成してFunctionsプロジェクトで読み込むことでIExtentionConfigProvider.initializeメソッドが呼び出されるようになります。

このメソッドでコンバータの登録とバインディングルールの登録を行います。 バインディングルールは出力バインディングの場合には、このAttributeが設定されている時には、このIAsyncCollector実装を呼び出すよ という設定を行います。

context.AddBindingRule<TweetAttribute>().BindToCollector<TweetMessage>(attr => new TweetAsyncCollector(attr));

Converterは様々な引数タイプに対応するために、IAsyncCollector実装のgenericタイプに変換するための処理を登録しておくイメージになります。

context.AddConverter<string, TweetMessage>(input => new TweetMessage() {Message = input});

以上な感じで実装してあげることでオリジナルな出力バインディングを作成することができます。

新しい出力バインディングを作っておいて使いまわしたい。

既存の出力バインディングの挙動が気に入らないので作りたい、なんて時に良いかもしれません。