LoginSignup
3
3

More than 3 years have passed since last update.

Azure Functions (C#) で ASP.NET Core っぽく DI を利用する

Last updated at Posted at 2019-08-30

概要

Azure Functions にて .NET Core で開発する際において、DIを用いた実装方法について纏めます。
ASP.NET Core にて利用したように、Serviceインスタンスの依存関係注入がやり易い形になっています。

公式のドキュメントは、下記になります。
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-dotnet-dependency-injection

以下、記事を参考にさせていただきました。
https://blog.shibayan.jp/entry/20190520/1558340113
https://qiita.com/HiroyukiSakoh/items/e9e472a92a53da4d7568

環境

  • Azure Functions v3
  • Windows10
  • Visual Studio 2019
  • .NET Core 3.1

コードサンプル

サンプルコードを Github にアップしています。
https://github.com/tYoshiyuki/azure-functions-di-sample
(※) コードサンプルを Azure Functions v3 に更新しました。

解説

公式の記事の通り、Microsoft.Azure.Functions.Extensions を Nuget より取得し、プロジェクトに加えます。
https://www.nuget.org/packages/Microsoft.Azure.Functions.Extensions/

Startup.cs にて DI の設定を行います。
実装例として、設定ファイルの読み込みとサービスのDI設定を行っています。

Startup.cs
[assembly: FunctionsStartup(typeof(Startup))]
namespace AzureFunctionsDiSample
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            var services = builder.Services;
            var provider = services.BuildServiceProvider();
            var configuration = provider.GetRequiredService<IConfiguration>();

            // 設定ファイルの内容をバインドする
            services.Configure<AppSettings>(configuration.GetSection("AppSettings"));

            // サービスのDI設定を行う
            services.AddTransient<IHelloService, HelloService>();
            services.AddTransient<IApplication, Application>();
        }
    }
}

コードサンプルは、以下のようにクラスのレイヤー分けを行っています。

クラス名 説明
EntryPoint Azure Functions のエントリーポイント
Application メインとなるアプリケーション
HelloService ビジネスロジックサービス

Azure Functions のエントリーポイントとなるクラス (EntryPoint.cs) から、
実際のアプリケーション処理を行うクラス、サービス処理を行うクラスを別レイヤーに切り出しています。
これにより、エントリーポイントとアプリケーションの依存関係を分離し、ユニットテストを実施し易い形にしています。

DIで設定したインスタンスは、コンストラクタインジェクションで受け取ります。
ASP.NET Core で利用する形と同じようなイメージになります。

EntryPoint.cs

public EntryPoint(IApplication application)
{
    _application = application;
}

[FunctionName("FunctionsDiSample")]
public IActionResult Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
    ILogger log)
{
    log.LogInformation("Function Run");

    _application.Run();

    return new OkObjectResult("Hello Functions DI Sample");
}

EntryPointでは Application を受け取り、また同様に Application では HelloService を受け取ります。
設定ファイルについては、IOptionsで受け取れます。

Application.cs

private readonly AppSettings _appSettings;
private readonly IHelloService _service;

public Application(ILogger<IApplication> logger, IOptions<AppSettings> optionsAccessor, IHelloService service) : base(logger)
{
    _appSettings = optionsAccessor.Value;
    _service = service;
}

ASP.NET Core で開発する際に意識するような クラスのレイヤー分け のノウハウが、
Azure Functionsでも生かせるようになり、今後の開発の幅が広がると思います。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3