.NET Azure Functions에서 종속성 주입 사용

Azure Functions는 클래스와 해당 종속성 간에 IoC(제어 반전)를 구현하는 기법인 DI(종속성 주입) 소프트웨어 디자인 패턴을 지원합니다.

  • Azure Functions의 종속성 주입은 .NET Core 종속성 주입 기능을 기반으로 합니다. .NET Core 종속성 주입에 대해 잘 알고 있는 것이 좋습니다. 종속성을 재정의하는 방법과 소비 계획에서 Azure Functions를 사용하여 구성 값을 읽는 방법에는 차이가 있습니다.

  • 종속성 주입에 대한 지원은 Azure Functions 2.x부터 시작합니다.

  • 종속성 주입 패턴은 C# 함수가 in-process 또는 out-of-process로 실행되는지에 따라 다릅니다.

Important

이 문서의 지침은 런타임과 함께 In-Process로 실행되는 C# 클래스 라이브러리 함수에만 적용됩니다. 이 사용자 지정 종속성 주입 모델은 .NET 함수를 out-of-process로 실행할 수 있는 .NET 격리 함수에는 적용되지 않습니다. .NET 격리 작업자 프로세스 모델은 일반 ASP.NET Core 종속성 주입 패턴을 사용합니다. 자세한 내용은 .NET 격리 작업자 프로세스 가이드의 종속성 주입을 참조하세요.

필수 조건

종속성 주입을 사용하려면 먼저 다음 NuGet 패키지를 설치해야 합니다.

서비스 등록

서비스를 등록하려면 구성 요소를 구성하고 IFunctionsHostBuilder 인스턴스에 추가하세요. Azure Functions 호스트는 인스턴스 IFunctionsHostBuilder 를 만들어 메서드에 직접 전달합니다.

Warning

소비 또는 프리미엄 계획에서 실행되는 함수 앱의 경우 트리거에 사용되는 구성 값을 수정하면 크기 조정 오류가 발생할 수 있습니다. 클래스에서 이러한 속성을 FunctionsStartup 변경하면 함수 앱 시작 오류가 발생합니다.

삽입하면 IConfiguration 예기치 않은 동작이 발생할 수 있습니다. 구성 원본을 추가하는 방법에 대한 자세한 내용은 구성 원본 사용자 지정을 참조 하세요.

메서드를 등록하려면 시작 시 사용되는 형식 이름을 지정하는 FunctionsStartup 어셈블리 특성을 추가합니다.

using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;

[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]

namespace MyNamespace;

public class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        builder.Services.AddHttpClient();

        builder.Services.AddSingleton<IMyService>((s) => {
            return new MyService();
        });

        builder.Services.AddSingleton<ILoggerProvider, MyLoggerProvider>();
    }
}

이 예제에서는 시작 시 등록 HttpClient 하는 데 필요한 Microsoft.Extensions.Http 패키지를 사용합니다.

제한 사항

런타임이 시작 클래스를 처리하기 전후로 일련의 등록 단계가 실행됩니다. 따라서 다음 사항에 유의하세요.

  • 시작 클래스는 설정 및 등록만을 위한 것입니다. 시작 시 등록되는 서비스를 시작 프로세스 중에 사용하지 마세요. 예를 들어 시작 시 등록되는 로거에 메시지를 로깅하려고 하지 마세요. 등록 프로세스의 이 시점은 서비스를 사용할 수 하기에는 너무 이르다. 메서드를 실행한 Configure 후 Functions 런타임은 다른 종속성을 계속 등록하므로 서비스가 작동하는 방식에 영향을 줄 수 있습니다.

  • 종속성 주입 컨테이너는 명시적으로 등록된 형식만 보유합니다. 삽입 가능한 형식으로 사용할 수 있는 유일한 서비스는 메서드에 Configure 설정된 서비스입니다. 따라서 함수 관련 형식은 설치 중에 또는 삽입 가능한 형식 BindingContextExecutionContext 으로 사용할 수 없습니다.

  • ASP.NET 인증 구성은 지원되지 않습니다. Functions 호스트는 핵심 수명 주기 작업에 대한 API를 제대로 노출하도록 ASP.NET 인증 서비스를 구성합니다. 사용자 지정 Startup 클래스의 다른 구성은 이 구성을 재정의하여 의도하지 않은 결과를 초래할 수 있습니다. 예를 들어 호출 builder.Services.AddAuthentication() 은 포털과 호스트 간의 인증을 중단하여 Azure Functions 런타임과 같은 메시지에 연결할 수 없습니다.

삽입된 종속성 사용

생성자 주입은 함수에서 종속성을 사용할 수 있도록 하는 데 사용됩니다. 생성자 주입을 사용하려면 삽입된 서비스 또는 함수 클래스에 정적 클래스를 사용하지 않아도 됩니다.

다음 샘플에서는 HTTP 트리거 함수에 IMyServiceHttpClient 종속성과 종속성을 삽입하는 방법을 보여 줍니다.

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

namespace MyNamespace;

public class MyHttpTrigger
{
    private readonly HttpClient _client;
    private readonly IMyService _service;

    public MyHttpTrigger(IHttpClientFactory httpClientFactory, IMyService service)
    {
        this._client = httpClientFactory.CreateClient();
        this._service = service;
    }

    [FunctionName("MyHttpTrigger")]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
        ILogger log)
    {
        var response = await _client.GetAsync("https://microsoft.com");
        var message = _service.GetMessage();

        return new OkObjectResult("Response from function with injected dependencies.");
    }
}

이 예제에서는 시작 시 등록 HttpClient 하는 데 필요한 Microsoft.Extensions.Http 패키지를 사용합니다.

서비스 수명

Azure Functions 앱은 ASP.NET 종속성 주입동일한 서비스 수명을 제공합니다. Functions 앱의 경우 다양한 서비스 수명이 다음과 같이 작동합니다.

  • 일시적: 임시 서비스는 서비스의 각 해결에 따라 생성됩니다.
  • 범위 지정: 범위가 지정된 서비스 수명이 함수 실행 수명과 일치합니다. 범위 지정 서비스는 함수 실행당 한 번씩 만들어집니다. 실행 중에 해당 서비스에 대한 이후 요청은 기존 서비스 인스턴스를 다시 사용합니다.
  • 싱글톤: 싱글톤 서비스 수명은 호스트 수명과 일치하며 해당 인스턴스의 함수 실행에서 다시 사용됩니다. 단일 수명 서비스는 연결 및 클라이언트(예: 인스턴스 DocumentClientHttpClient )에 권장됩니다.

GitHub에서 다양한 서비스 수명 샘플을 보거나 다운로드하세요.

로깅 서비스

사용자 고유의 ILoggerProvider로깅 공급자가 필요한 경우 Microsoft.Extensions.Logging.Abstractions NuGet 패키지를 통해 사용할 수 있는 사용자 지정 형식을 인스턴스로 등록합니다.

Application Insights는 Azure Functions에 의해 자동으로 추가됩니다.

Warning

  • 환경에서 제공하는 서비스와 충돌하는 서비스를 등록하는 서비스 컬렉션에 추가 AddApplicationInsightsTelemetry() 하지 마세요.
  • 직접 TelemetryConfigurationTelemetryClient 등록하거나 기본 제공 Application Insights 기능을 사용하는 경우 등록하지 마세요. 사용자 고유 TelemetryClient 의 인스턴스를 구성해야 하는 경우 C# 함수의 로그 사용자 지정 원격 분석에 표시된 대로 삽입된 TelemetryConfiguration 인스턴스를 통해 인스턴스를 만듭니다.

ILogger<T> 및 ILoggerFactory

호스트는 생성자에 및 ILoggerFactory 서비스를 삽입 ILogger<T> 합니다. 그러나 기본적으로 이러한 새 로깅 필터는 함수 로그에서 필터링됩니다. 추가 필터 및 범주에 host.json 옵트인하도록 파일을 수정해야 합니다.

다음 예제에서는 호스트에 ILogger<HttpTrigger> 노출 되는 로그를 추가 하는 방법을 보여 줍니다.

namespace MyNamespace;

public class HttpTrigger
{
    private readonly ILogger<HttpTrigger> _log;

    public HttpTrigger(ILogger<HttpTrigger> log)
    {
        _log = log;
    }

    [FunctionName("HttpTrigger")]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req)
    {
        _log.LogInformation("C# HTTP trigger function processed a request.");

        // ...
}

다음 예제 host.json 파일은 로그 필터를 추가합니다.

{
    "version": "2.0",
    "logging": {
        "applicationInsights": {
            "samplingSettings": {
                "isEnabled": true,
                "excludedTypes": "Request"
            }
        },
        "logLevel": {
            "MyNamespace.HttpTrigger": "Information"
        }
    }
}

로그 수준에 대한 자세한 내용은 로그 수준 구성을 참조하세요.

함수 앱 제공 서비스

함수 호스트는 많은 서비스를 등록합니다. 다음 서비스는 애플리케이션에서 종속성으로 안전하게 사용할 수 있습니다.

서비스 유형 수명(lifetime) 설명
Microsoft.Extensions.Configuration.IConfiguration 싱글톤 런타임 구성
Microsoft.Azure.WebJobs.Host.Executors.IHostIdProvider 싱글톤 호스트 인스턴스의 ID 제공 담당

종속성을 적용하려는 다른 서비스가 있는 경우 문제를 만들고 GitHub에서 제안합니다.

호스트 서비스 재정의

호스트에서 제공하는 서비스 재정의는 현재 지원되지 않습니다. 재정의하려는 서비스가 있는 경우 문제를 만들고 GitHub에서 제안합니다.

옵션 및 설정 작업

앱 설정정의된 값은 인스턴스에서 IConfiguration 사용할 수 있으므로 시작 클래스에서 앱 설정 값을 읽을 수 있습니다.

IConfiguration 인스턴스에서 사용자 지정 형식으로 값을 추출할 수 있습니다. 앱 설정 값을 사용자 지정 형식으로 복사하면 이러한 값을 주입 가능하게 만들어 서비스를 쉽게 테스트할 수 있습니다. 구성 인스턴스를 읽는 설정 간단한 키/값 쌍이어야 합니다. Elastic Premium 계획에서 실행되는 함수의 경우 애플리케이션 설정 이름에는 문자, 숫자(), 마침표(0-9), 콜론(.) 및 밑줄(:_)만 포함될 수 있습니다. 자세한 내용은 앱 설정 고려 사항을 참조 하세요.

앱 설정과 일치하는 속성이 포함된 다음 클래스를 고려합니다.

public class MyOptions
{
    public string MyCustomSetting { get; set; }
}

local.settings.json 사용자 지정 설정을 다음과 같이 구성할 수 있는 파일은 다음과 같습니다.

{
  "IsEncrypted": false,
  "Values": {
    "MyOptions:MyCustomSetting": "Foobar"
  }
}

Startup.Configure 메서드 내에서 다음 코드를 사용하여 IConfiguration 인스턴스에서 사용자 지정 형식으로 값을 추출할 수 있습니다.

builder.Services.AddOptions<MyOptions>()
    .Configure<IConfiguration>((settings, configuration) =>
    {
        configuration.GetSection("MyOptions").Bind(settings);
    });

Bind를 호출하면 구성의 속성 이름과 일치하는 값이 사용자 지정 인스턴스로 복사됩니다. 이제 IoC 컨테이너에서 옵션 인스턴스를 사용하여 함수에 삽입할 수 있습니다.

options 개체는 제네릭 IOptions 인터페이스의 인스턴스로 함수에 삽입됩니다. 속성을 Value 사용하여 구성에 있는 값에 액세스합니다.

using System;
using Microsoft.Extensions.Options;

public class HttpTrigger
{
    private readonly MyOptions _settings;

    public HttpTrigger(IOptions<MyOptions> options)
    {
        _settings = options.Value;
    }
}

자세한 내용은 ASP.NET Core의 옵션 패턴을 참조 하세요.

ASP.NET Core 사용자 비밀 사용

로컬로 앱을 개발할 때 ASP.NET Core는 프로젝트 루트 외부에 비밀 정보를 저장할 수 있는 비밀 관리자 도구를 제공합니다. 비밀이 실수로 소스 제어에 커밋되는 가능성이 줄어듭니다. Azure Functions Core Tools(버전 3.0.3233 이상)는 ASP.NET Core Secret Manager에서 만든 비밀을 자동으로 읽습니다.

사용자 비밀을 이용하도록 .NET Azure Functions 프로젝트를 구성하려면 프로젝트 루트에서 다음 명령을 실행합니다.

dotnet user-secrets init

그런 다음, dotnet user-secrets set 명령을 사용하여 비밀을 만들거나 업데이트합니다.

dotnet user-secrets set MySecret "my secret value"

함수 앱 코드에서 사용자 비밀 값에 액세스하려면 사용 IConfiguration 하거나 IOptions.

구성 원본 사용자 지정

다른 구성 원본을 지정하려면 함수 앱의 클래스에서 메서드를 재정 ConfigureAppConfigurationStartUp 합니다.

다음 샘플에서는 기본 및 선택적 환경별 앱 설정 파일 모두에서 구성 값을 추가합니다.

using System.IO;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]

namespace MyNamespace;

public class Startup : FunctionsStartup
{
    public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
    {
        FunctionsHostBuilderContext context = builder.GetContext();

        builder.ConfigurationBuilder
            .AddJsonFile(Path.Combine(context.ApplicationRootPath, "appsettings.json"), optional: true, reloadOnChange: false)
            .AddJsonFile(Path.Combine(context.ApplicationRootPath, $"appsettings.{context.EnvironmentName}.json"), optional: true, reloadOnChange: false)
            .AddEnvironmentVariables();
    }
    
    public override void Configure(IFunctionsHostBuilder builder)
    {
    }
}

의 속성IFunctionsConfigurationBuilder에 구성 공급자를 ConfigurationBuilder 추가합니다. 구성 공급자 사용에 대한 자세한 내용은 ASP.NET Core의 구성을 참조 하세요.

A FunctionsHostBuilderContext 는 .에서 IFunctionsConfigurationBuilder.GetContext()가져옵니다. 이 컨텍스트를 사용하여 현재 환경 이름을 검색하고 함수 앱 폴더의 구성 파일 위치를 확인합니다.

기본적으로 이러한 appsettings.json 구성 파일은 함수 앱의 출력 폴더에 자동으로 복사되지 않습니다. .csproj 파일이 복사되도록 다음 샘플과 일치하도록 파일을 업데이트합니다.

<None Update="appsettings.json">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>      
</None>
<None Update="appsettings.Development.json">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    <CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>

다음 단계

자세한 내용은 다음 리소스를 참조하세요.