Azure Functions を使用する C# クラス ライブラリ関数を開発する

この記事では、.NET クラス ライブラリの C# を使用した Azure Functions 開発の概要を示します。

重要

この記事では、ランタイムを使用してインプロセスで実行される .NET クラス ライブラリ関数をサポートしています。 C# 関数では、アウトプロセスを実行したり、Functions ランタイムから分離したりすることもできます。 分離ワーカー プロセス モデルは、現在のバージョンの Functions ランタイムで非 LTS バージョンの .NET および.NET Framework アプリを実行する唯一の方法です。 詳細については、.NET 分離ワーカー プロセス関数に関する記事を参照してください。 分離ワーカー プロセスとインプロセスの .NET 関数の包括的な比較については、「インプロセスと分離ワーカー プロセスの .NET Azure Functions の違い」を参照してください。

C# 開発者の方は、次の記事のいずれかに関心があるかもしれません。

作業の開始 概念 ガイド付き学習とサンプル

Azure Functions では、C# および C# スクリプト プログラミング言語をサポートします。 Azure Portal での C# の使用に関するガイダンスを探している場合は、C# スクリプト (.csx) 開発者向けリファレンスをご覧ください。

サポートされているバージョン

Functions ランタイムの各バージョンは、.NET の特定のバージョンと動作します。 Functions のバージョンの詳細については、「Azure Functions ランタイム バージョンの概要」を参照してください。 バージョンのサポートは、関数がインプロセスで実行されるか、分離ワーカー プロセスで実行されるかによって異なります。

注意

関数アプリで使用される Functions ランタイム バージョンを変更する方法については、「現在のランタイム バージョンの表示と更新」を参照してください。

次の表は、特定のバージョンの Functions と共に使用できる最上位レベルの .NET Core と .NET Framework を示しています。

Functions ランタイムのバージョン インプロセス
(.NET クラス ライブラリ)
分離ワーカー プロセス
(.NET 分離)
Functions 4.x .NET 6.0 .NET 6.0
.NET 7.0 (GA)1
.NET Framework 4.8 (GA)1
Functions 1.x .NET Framework 4.8 N/A

1 ビルド プロセスには .NET 6 SDK も必要です。

特定の古いマイナー バージョンの削除など、Azure Functions リリースに関する最新のニュースについては、Azure App Service のお知らせを閲覧してください。

関数クラス ライブラリ プロジェクト

Visual Studio では、Azure Functions プロジェクト テンプレートは、次のファイルを含む C# クラス ライブラリ プロジェクトを作成します。

  • host.json - ローカルまたは Azure 内で実行される場合に、プロジェクト内のすべての関数に影響を及ぼす構成設定を格納します。
  • local.settings.json - ローカルで実行される場合に使用されるアプリ設定および接続文字列を格納します。 このファイルにはシークレットが含まれていて、Azure の関数アプリには公開されません。 代わりに、関数アプリにアプリ設定を追加します。

プロジェクトをビルドするときに、次の例のようなフォルダー構造がビルドの出力ディレクトリに作成されます。

<framework.version>
 | - bin
 | - MyFirstFunction
 | | - function.json
 | - MySecondFunction
 | | - function.json
 | - host.json

このディレクトリは、Azure 上で関数アプリにデプロイされるディレクトリです。 Functions ランタイムのバージョン 2.x に必要なバインディング拡張機能は、NuGet パッケージとしてプロジェクトに追加されます。

重要

ビルド処理では、関数ごとに function.json ファイルが作成されます。 この function.json ファイルに対しては、直接編集は行われません。 このファイルを編集して、バインド構成を変更したり、関数を無効にしたりすることはできません。 関数を無効にする方法については、関数を無効にする方法に関するページをご覧ください。

関数として認識されるメソッド

次の例に示すように、クラス ライブラリでは、関数は FunctionName とトリガー属性を使用したメソッドです。

public static class SimpleExample
{
    [FunctionName("QueueTrigger")]
    public static void Run(
        [QueueTrigger("myqueue-items")] string myQueueItem, 
        ILogger log)
    {
        log.LogInformation($"C# function processed: {myQueueItem}");
    }
} 

FunctionName 属性は、関数のエントリ ポイントとしてメソッドをマークします。 名前はプロジェクト内で一意であり、文字で始まり、英数字、_- のみが含まれ、127 文字以下にする必要があります。 プロジェクト テンプレートでは、多くの場合、Run という名前のメソッドが作成されますが、有効な C# メソッド名であればメソッド名として使用できます。 上記の例では静的メソッドが使用されていますが、関数を静的にする必要はありません。

トリガー属性は、トリガーの種類を指定し、メソッド パラメーターに入力データをバインドします。 例の関数は 1 つのクエリ メッセージによってトリガーされ、そのクエリ メッセージは myQueueItem パラメーターでメソッドに渡されます。

メソッド シグネチャのパラメーター

メソッド シグネチャには、トリガー属性で使用されているもの以外のパラメーターが含まれる場合があります。 含めることができるその他のパラメーターの一部を以下に示します。

  • 属性で修飾することによってそのようにマークした入出力のバインド
  • TraceWriterのための ILogger または TraceWriter (ILogger) パラメーター。
  • CancellationTokenのための CancellationToken パラメーター。
  • トリガー メタデータを取得するためのバインド式パラメーター。

関数シグネチャ内のパラメーターの順序は問題ではありません。 たとえば、トリガー パラメーターは、他のバインドの前後に配置できます。また、ロガー パラメーターは、トリガー パラメーターまたはバインド パラメーターの前後に配置できます。

出力バインディング

関数には、出力パラメーターを使って、0 個または複数の出力バインドを定義できます。

次の例では、myQueueItemCopy という名前の出力キュー バインドを追加することで、前のものを変更しています。 この関数は、関数をトリガーするメッセージの内容を、異なるキュー内の新しいメッセージに書き込みます。

public static class SimpleExampleWithOutput
{
    [FunctionName("CopyQueueMessage")]
    public static void Run(
        [QueueTrigger("myqueue-items-source")] string myQueueItem, 
        [Queue("myqueue-items-destination")] out string myQueueItemCopy,
        ILogger log)
    {
        log.LogInformation($"CopyQueueMessage function processed: {myQueueItem}");
        myQueueItemCopy = myQueueItem;
    }
}

出力バインドに代入された値は、関数が終了したときに書き込まれます。 1 つの関数で複数の出力バインドを使用するには、複数の出力パラメーターに値を代入するだけです。

バインドの参照についての記事 (たとえば「Storage キュー」) では、トリガー、入力、または出力のバインド属性で、どのパラメーターの種類を使用できるかを説明しています。

バインド式の例

次のコードでは、アプリ設定から監視するキューの名前を取得し、insertionTime パラメーターで、キュー メッセージの作成時刻を取得しています。

public static class BindingExpressionsExample
{
    [FunctionName("LogQueueMessage")]
    public static void Run(
        [QueueTrigger("%queueappsetting%")] string myQueueItem,
        DateTimeOffset insertionTime,
        ILogger log)
    {
        log.LogInformation($"Message content: {myQueueItem}");
        log.LogInformation($"Created at: {insertionTime}");
    }
}

自動生成される function.json

ビルド処理では、ビルド フォルダー内の関数フォルダーに function.jsonファイルを作成します。 前述のとおり、このファイルに対しては直接編集が行われません。 このファイルを編集して、バインド構成を変更したり、関数を無効にしたりすることはできません。

このファイルの目的は、従量課金プランでのスケーリングの判断に使用するスケール コントローラーに情報を提供することです。 このため、ファイルにはトリガー情報のみが含まれ、入力および出力バインドは含まれません。

生成された function.json ファイルには、function.json 構成ではなく、バインドの .NET 属性を使用するようにランタイムに指示する プロパティが含まれます。 次に例を示します。

{
  "generatedBy": "Microsoft.NET.Sdk.Functions-1.0.0.0",
  "configurationSource": "attributes",
  "bindings": [
    {
      "type": "queueTrigger",
      "queueName": "%input-queue-name%",
      "name": "myQueueItem"
    }
  ],
  "disabled": false,
  "scriptFile": "..\\bin\\FunctionApp1.dll",
  "entryPoint": "FunctionApp1.QueueTrigger.Run"
}

Microsoft.NET.Sdk.Functions

function.json ファイルの生成は、NuGet パッケージ (Microsoft.NET.Sdk.Functions) によって実行されます。

次の例は、同じ Sdk パッケージの異なるターゲット フレームワークを持つ .csproj ファイルの関連部分を示しています。

<PropertyGroup>
  <TargetFramework>net6.0</TargetFramework>
  <AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
  <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.1.1" />
</ItemGroup>

Sdk パッケージ間の依存関係はトリガーとバインドです。 1.x のトリガーとバインドの対象は .NET Framework であるため、1.x プロジェクトは 1.x のトリガーとバインドを参照します。一方、4.x のトリガーとバインドの対象は .NET Core です。

Sdk パッケージも、Sdk に依存しており、間接的に WindowsAzure.Storage に依存します。 これらの依存関係により、ユーザーのプロジェクトでは、必ずそのプロジェクト用の Functions ランタイム バージョンで動作するパッケージ バージョンが使用されます。 たとえば、Newtonsoft.Json のバージョンが .NET Framework 4.6.1 用のバージョン 11 だとします。ところが、.NET Framework 4.6.1 を対象とする Functions ランタイムは Newtonsoft.Json 9.0.1 としか互換性がありません。 この場合は、そのプロジェクトの関数コードも Newtonsoft.Json 9.0.1 を使用する必要があります。

Microsoft.NET.Sdk.Functions のソース コードは、GitHub リポジトリ (Microsoft.NET.Sdk.Functions) で利用できます。

ローカルのランタイム バージョン

Visual Studio では、ローカル コンピュータ上で Azure Functions Core Tools を使用して、Functions プロジェクトを実行します。 Core Tools は、Functions ランタイム用のコマンド ライン インターフェイスです。

Windows インストーラー (MSI) パッケージを使用するか npm を使用して Core Tools をインストールした場合、Visual Studio で使用される Core Tools のバージョンには影響ありません。 Functions ランタイム バージョン 1.x の場合、Visual Studio は Core Tools のバージョンを %USERPROFILE%\AppData\Local\Azure.Functions.Cli に格納し、そこに格納されている中で最も新しいバージョンを使用します。 Functions 4.x の場合、Core Tools は Azure Functions と Web ジョブ ツールの拡張機能に含まれます。 Functions 1.x の場合、Functions プロジェクトを実行すると、コンソール出力で使用されているバージョンを確認できます。

[3/1/2018 9:59:53 AM] Starting Host (HostId=contoso2-1518597420, Version=2.0.11353.0, ProcessId=22020, Debug=False, Attempt=0, FunctionsExtensionVersion=)

ReadyToRun

関数アプリは ReadyToRun バイナリとしてコンパイルできます。 ReadyToRun は、事前コンパイル形式であり、起動時のパフォーマンスを向上させることができます。これは、従量課金プランで実行される場合にコールドスタートの影響を軽減するのに役立ちます。

ReadyToRun は .NET 6 以降のバージョンで使用可能であり、Azure Functions ランタイムのバージョン 4.0 が必要です。

プロジェクトを ReadyToRun としてコンパイルするには、<PublishReadyToRun> および <RuntimeIdentifier> 要素を追加して、プロジェクト ファイルを更新します。 Windows 32 ビットの関数アプリに公開するための構成を以下に示します。

<PropertyGroup>
  <TargetFramework>net6.0</TargetFramework>
  <AzureFunctionsVersion>v4</AzureFunctionsVersion>
  <PublishReadyToRun>true</PublishReadyToRun>
  <RuntimeIdentifier>win-x86</RuntimeIdentifier>
</PropertyGroup>

重要

.NET 6 以降、複合 ReadyToRun コンパイルのサポートが追加されました。 ReadyToRun クロス プラットフォームとアーキテクチャの制限事項を確認してください。

コマンド ラインから ReadyToRun を使用してアプリをビルドすることもできます。 詳細については、「dotnet publish」の -p:PublishReadyToRun=true オプションの説明を参照してください。

バインドでサポートされる型

各バインドには独自にサポートされる型があります。たとえば、BLOB トリガー属性は文字列パラメーター、POCO パラメーター、CloudBlockBlob パラメーター、またはサポートされるその他の複数の型のいずれかに適用できます。 BLOB バインディングのバインド リファレンスに関する記事に、サポートされるすべてのパラメーター型の一覧が示されています。 詳細については、トリガーとバインドに関する記事と、各バインドの種類に対応するバインド リファレンス ドキュメントをご覧ください。

ヒント

HTTP または Webhook のバインディングを使用する予定がある場合は、不適切な HttpClient のインスタンス化によって生じるおそれのあるポートの枯渇を防止してください。 詳細については、「How to manage connections in Azure Functions」(Azure Functions で接続を管理する方法) を参照してください。

メソッドの戻り値へのバインド

出力バインドのメソッドの戻り値を使用するには、属性をメソッドの戻り値に適用します。 例については、トリガーとバインディングに関するページを参照してください。

正常な関数の実行によって、常に戻り値が出力バインドに渡される場合のみ、戻り値を使用してください。 それ以外の場合は、次のセクションに示すように ICollector または IAsyncCollector を使用してください。

複数の出力値の書き込み

1 つの出力バインドに複数の値を書き込むため、または正常な関数の呼び出しによって出力バインドに渡される値がない場合、ICollector または IAsyncCollector 型を使用してください。 これらの型は、メソッド完了時に出力バインドに書き込まれる、書き込み専用接続です。

この例では、ICollector を使用して複数のキュー メッセージを同じキューに書き込みます。

public static class ICollectorExample
{
    [FunctionName("CopyQueueMessageICollector")]
    public static void Run(
        [QueueTrigger("myqueue-items-source-3")] string myQueueItem,
        [Queue("myqueue-items-destination")] ICollector<string> myDestinationQueue,
        ILogger log)
    {
        log.LogInformation($"C# function processed: {myQueueItem}");
        myDestinationQueue.Add($"Copy 1: {myQueueItem}");
        myDestinationQueue.Add($"Copy 2: {myQueueItem}");
    }
}

非同期

関数を非同期にするには、 キーワードを使用して Task オブジェクトを返します。

public static class AsyncExample
{
    [FunctionName("BlobCopy")]
    public static async Task RunAsync(
        [BlobTrigger("sample-images/{blobName}")] Stream blobInput,
        [Blob("sample-images-copies/{blobName}", FileAccess.Write)] Stream blobOutput,
        CancellationToken token,
        ILogger log)
    {
        log.LogInformation($"BlobCopy function processed.");
        await blobInput.CopyToAsync(blobOutput, 4096, token);
    }
}

非同期関数では out パラメーターを使用できません。 出力バインドには、代わりに関数の戻り値またはコレクター オブジェクトを使用します。

キャンセル トークン

関数は CancellationToken パラメーターを受け付けることができます。これにより、オペレーティング システムは、その関数をいつ終了しようとしているかをコードに通知できます。 この通知を使用すれば、関数が予期せず終了してデータが不整合な状態になることを防止できます。

メッセージをバッチで処理する関数を持っている場合について考えてみましょう。 Azure Service Bus によってトリガーされる次の関数によって、Message オブジェクトの配列が処理されます。これは、特定の関数呼び出しによって処理される受信メッセージのバッチを表しています。

using Microsoft.Azure.ServiceBus;
using System.Threading;

namespace ServiceBusCancellationToken
{
    public static class servicebus
    {
        [FunctionName("servicebus")]
        public static void Run([ServiceBusTrigger("csharpguitar", Connection = "SB_CONN")]
               Message[] messages, CancellationToken cancellationToken, ILogger log)
        {
            try
            { 
                foreach (var message in messages)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        log.LogInformation("A cancellation token was received. Taking precautionary actions.");
                        //Take precautions like noting how far along you are with processing the batch
                        log.LogInformation("Precautionary activities --complete--.");
                        break;
                    }
                    else
                    {
                        //business logic as usual
                        log.LogInformation($"Message: {message} was processed.");
                    }
                }
            }
            catch (Exception ex)
            {
                log.LogInformation($"Something unexpected happened: {ex.Message}");
            }
        }
    }
}

ログ記録

関数のコードで、Application Insights でトレースとして表示されるログに出力を書き込むことができます。 ログ書き込みには、ILogger という種類のパラメーターを含める方法をお勧めします。これは通常 という名前です。 Functions バージョン 1.x のランタイムでは TraceWriter が使用されていました。ここでは Application Insights への書き込みは行われますが、構造化ログはサポートされていません。 このデータは Application Insights によってキャプチャされないため、ログの書き込みに Console.Write を使用しないでください。

ILogger

関数定義に、構造化ログをサポートする ILogger パラメーターを含めます。

ILogger オブジェクトで、Log<level>ILogger を呼び出して、ログを作成します。 次のコードでは、カテゴリが Function.<YOUR_FUNCTION_NAME>.User.Information ログが書き込まれます。

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, ILogger logger)
{
    logger.LogInformation("Request for item with key={itemKey}.", id);

関数がどのように ILogger を実装しているかについて詳しくは、「ILogger」を参照してください。 Function で始まるカテゴリは、ILogger インスタンスを使用していると想定しています。 代わりに ILogger<T> を使用する場合、カテゴリ名は代わりに T に基づいている場合があります。

構造化ログ

ログ メッセージで使用するパラメーターは、プレースホルダーの名前ではなく順序によって決定されます。 次のコードがあるとします。

string partitionKey = "partitionKey";
string rowKey = "rowKey";
logger.LogInformation("partitionKey={partitionKey}, rowKey={rowKey}", partitionKey, rowKey);

同じメッセージ文字列を維持しながらパラメーターの順序を逆にすると、結果のメッセージ テキストではそれらの値が誤った場所に配置されます。

プレースホルダーはこのように処理されるため、構造化ログを実行できます。 Application Insights では、パラメーターの名前と値のペア、およびメッセージ文字列を保存します。 そのため、メッセージ引数はクエリ可能なフィールドになります。

前の例のようなロガー メソッド呼び出しでは、フィールド customDimensions.prop__rowKey をクエリできます。 prop__ プレフィックスを追加して、ランタイムが追加したフィールドと、ご使用の関数コードが追加したフィールドとの間に競合が起こらないようにします。

フィールド customDimensions.prop__{OriginalFormat} を参照することで、元のメッセージ文字列をクエリすることもできます。

customDimensions データの JSON 表現の例を次に示します。

{
  "customDimensions": {
    "prop__{OriginalFormat}":"C# Queue trigger function processed: {message}",
    "Category":"Function",
    "LogLevel":"Information",
    "prop__message":"c9519cbf-b1e6-4b9b-bf24-cb7d10b1bb89"
  }
}

カスタム テレメトリをログに記録する

ご自身の関数からカスタム テレメトリ データを Application Insights に送信するときに使用できる、Application Insights SDK の Functions 固有のバージョンがあります。Microsoft.Azure.WebJobs.Logging.ApplicationInsights。 コマンド プロンプトから次のコマンドを使用して、このパッケージをインストールします。

dotnet add package Microsoft.Azure.WebJobs.Logging.ApplicationInsights --version <VERSION>

このコマンドでは、<VERSION> を、このパッケージのバージョンに置き換えます。このバージョンでは、インストールされている <VERSION> バージョンがサポートされます。

次の C# の例では、カスタム テレメトリ API を使用します。 この例は .NET クラス ライブラリ用ですが、Application Insights のコードは C# スクリプト用と同じです。

バージョン 2.x 以降のランタイム バージョンでは、テレメトリを現在の操作と自動的に関連付けるために、Application Insights 内のより新しい機能が使用されます。 IdParentId、または Name フィールドを手動で設定する操作は必要ありません。

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using System.Linq;

namespace functionapp0915
{
    public class HttpTrigger2
    {
        private readonly TelemetryClient telemetryClient;

        /// Using dependency injection will guarantee that you use the same configuration for telemetry collected automatically and manually.
        public HttpTrigger2(TelemetryConfiguration telemetryConfiguration)
        {
            this.telemetryClient = new TelemetryClient(telemetryConfiguration);
        }

        [FunctionName("HttpTrigger2")]
        public Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)]
            HttpRequest req, ExecutionContext context, ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");
            DateTime start = DateTime.UtcNow;

            // Parse query parameter
            string name = req.Query
                .FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
                .Value;

            // Write an event to the customEvents table.
            var evt = new EventTelemetry("Function called");
            evt.Context.User.Id = name;
            this.telemetryClient.TrackEvent(evt);

            // Generate a custom metric, in this case let's use ContentLength.
            this.telemetryClient.GetMetric("contentLength").TrackValue(req.ContentLength);

            // Log a custom dependency in the dependencies table.
            var dependency = new DependencyTelemetry
            {
                Name = "GET api/planets/1/",
                Target = "swapi.co",
                Data = "https://swapi.co/api/planets/1/",
                Timestamp = start,
                Duration = DateTime.UtcNow - start,
                Success = true
            };
            dependency.Context.User.Id = name;
            this.telemetryClient.TrackDependency(dependency);

            return Task.FromResult<IActionResult>(new OkResult());
        }
    }
}

この例では、カスタム メトリック データは、customMetrics テーブルに送信される前にホストによって集計されます。 詳細については、Application Insights で GetMetric のドキュメントを参照してください。

ローカルで実行する場合は、Application Insights キーを使用して APPINSIGHTS_INSTRUMENTATIONKEY 設定を APPINSIGHTS_INSTRUMENTATIONKEY ファイルに追加する必要があります。

関数呼び出しの要求が重複するため、TrackRequestStartOperation<RequestTelemetry> を呼び出さないでください。 Functions ランタイムでは、要求が自動的に追跡されます。

telemetryClient.Context.Operation.Id は設定しないでください。 このグローバル設定により、多くの関数が同時に実行されていると、正しくない相関関係が発生します。 代わりに、新しいテレメトリ インスタンス (DependencyTelemetryEventTelemetry) を作成し、その Context プロパティを変更してください。 その後、テレメトリ インスタンスを、TelemetryClient (TrackDependency()TrackEvent()TrackMetric()) の対応する Track メソッドに渡します。 このメソッドにより、現在の関数呼び出しについて、テレメトリが必ず正しい相関関係の詳細を持つようになります。

関数のテスト

以下の記事では、テストを目的として、インプロセス C# クラス ライブラリ関数をローカルで実行する方法について説明します。

環境変数

環境変数またはアプリ設定値を取得するには、次のコード例のように、 System.Environment.GetEnvironmentVariableを使用します。

public static class EnvironmentVariablesExample
{
    [FunctionName("GetEnvironmentVariables")]
    public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
    {
        log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
        log.LogInformation(GetEnvironmentVariable("AzureWebJobsStorage"));
        log.LogInformation(GetEnvironmentVariable("WEBSITE_SITE_NAME"));
    }

    private static string GetEnvironmentVariable(string name)
    {
        return name + ": " +
            System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
    }
}

アプリ設定は、ローカルでの開発中と Azure での実行中の両方で、環境変数から読み取ることができます。 ローカルでの開発時、アプリ設定は Values ファイルの Values コレクションから取得します。 ローカルと Azure の両方の環境において、GetEnvironmentVariable("<app setting name>") は名前付きアプリ設定の値を取得します。 たとえば、ローカルでの実行中、local.settings.json ファイルに が含まれている場合は、"My Site Name" が返されます。

System.Configuration.ConfigurationManager.AppSettings プロパティは、アプリ設定値を取得するための代替 API ですが、次に示すように を使用することをお勧めします。

実行時のバインド

C# および他の .NET 言語では、属性の宣言型のバインドではなく命令型のバインド パターンを使用できます。 命令型のバインドは、設計時ではなくランタイム時にバインド パラメーターを計算する必要がある場合に便利です。 このパターンを使用すると、サポートされている入力バインドと出力バインドに関数コード内でバインドできます。

次のように命令型のバインドを定義します。

  • 必要な命令型のバインドの関数署名に属性を含めないでください。

  • 入力パラメーター Binder binder または IBinder binder を渡します。

  • 次の C# パターンを使用してデータ バインドを実行します。

    using (var output = await binder.BindAsync<T>(new BindingTypeAttribute(...)))
    {
        ...
    }
    

    BindingTypeAttribute はバインドを定義する .NET 属性、T はそのバインドの種類でサポートされている入力または出力の型です。 Tout パラメーター型 (out JObject など) にすることはできません。 たとえば、Mobile Apps テーブルの出力バインドでは 6 種類の出力がサポートされますが、命令型のバインドに使用できるのは ICollectorT または IAsyncCollectorT> のみです。

単一属性の例

次のコード例は、実行時に BLOB パスが定義された Storage Blob の出力バインドを作成し、この BLOB に文字列を書き込みます。

public static class IBinderExample
{
    [FunctionName("CreateBlobUsingBinder")]
    public static void Run(
        [QueueTrigger("myqueue-items-source-4")] string myQueueItem,
        IBinder binder,
        ILogger log)
    {
        log.LogInformation($"CreateBlobUsingBinder function processed: {myQueueItem}");
        using (var writer = binder.Bind<TextWriter>(new BlobAttribute(
                    $"samples-output/{myQueueItem}", FileAccess.Write)))
        {
            writer.Write("Hello World!");
        };
    }
}

BlobAttributeStorage Blob の入力バインドまたは出力バインドを定義します。TextWriter はサポートされている出力バインドの種類です。

複数属性の例

前の例では、関数アプリのメイン ストレージ アカウント接続文字列 (AzureWebJobsStorage) のアプリ設定を取得します。 ストレージ アカウントに使用するカスタム アプリ設定を指定するには、StorageAccountAttribute を追加し、属性の配列を に渡します。 IBinderではなく、Binder パラメーターを使用します。 次に例を示します。

public static class IBinderExampleMultipleAttributes
{
    [FunctionName("CreateBlobInDifferentStorageAccount")]
    public async static Task RunAsync(
            [QueueTrigger("myqueue-items-source-binder2")] string myQueueItem,
            Binder binder,
            ILogger log)
    {
        log.LogInformation($"CreateBlobInDifferentStorageAccount function processed: {myQueueItem}");
        var attributes = new Attribute[]
        {
        new BlobAttribute($"samples-output/{myQueueItem}", FileAccess.Write),
        new StorageAccountAttribute("MyStorageAccount")
        };
        using (var writer = await binder.BindAsync<TextWriter>(attributes))
        {
            await writer.WriteAsync("Hello World!!");
        }
    }
}

トリガーとバインド

この表は、Azure Functions のメジャー バージョンのランタイムでサポートされているバインディングを示しています。

Type 1.x 2.x 以降1 トリガー 入力 出力
Blob Storage
Azure Cosmos DB
Azure SQL (プレビュー)2
Dapr3
Event Grid
Event Hubs
HTTP と Webhook
IoT Hub
Kafka2
Mobile Apps
Notification Hubs
Queue Storage
RabbitMQ2
SendGrid
Service Bus
SignalR
Table Storage
Timer
Twilio

1 バージョン 2.x ランタイム以降では、HTTP と Timer を除くすべてのバインドを登録する必要があります。 「バインディング拡張機能を登録する」を参照してください。

2 トリガーは従量課金プランでサポートされていません。 ランタイム駆動のトリガーが必要です。

3 Kubernetes、IoT Edge、およびその他の自己ホスト型モードでのみサポートされます。

次のステップ