학습
모듈
ASP.NET Core에서 종속성 주입을 사용하여 서비스 구성 - Training
ASP.NET Core 앱에서 종속성 주입을 파악하고 구현합니다. ASP.NET Core의 기본 제공 서비스 컨테이너를 사용하여 종속성을 관리합니다. 서비스 컨테이너에 서비스를 등록합니다.
장기 실행 서비스를 만드는 데는 다음과 같은 여러 가지 이유가 있습니다.
백그라운드 서비스 처리에는 일반적으로 UI(사용자 인터페이스)가 포함되지 않지만 UI를 기반으로 빌드할 수 있습니다. .NET Framework 초기에는 Windows 개발자가 이러한 목적으로 Windows Services를 만들 수 있었습니다. 이제 .NET을 사용하여 IHostedService(을)를 구현하는 BackgroundService(을)를 사용하거나 직접 구현할 수 있습니다.
.NET을 사용하면 더 이상 Windows에 제한되지 않습니다. 플랫폼 간 백그라운드 서비스를 개발할 수 있습니다. 호스트된 서비스는 로깅, 구성 및 DI(종속성 주입)를 준비합니다. 라이브러리 확장 모음의 일부로, 이는 제네릭 호스트에서 작동하는 모든 .NET 워크로드의 기본 사항임을 의미합니다.
중요
.NET SDK를 설치하면 Microsoft.NET.Sdk.Worker
및 작업자 템플릿도 설치됩니다. 즉, .NET SDK를 설치한 후 dotnet new Worker 명령을 사용하여 새 작업자를 만들 수 있습니다. Visual Studio를 사용하는 경우 선택적 ASP.NET 및 웹 개발 워크로드가 설치될 때까지 템플릿이 숨겨집니다.
많은 용어가 동의어로 잘못 사용됩니다. 이 섹션에서는 이 문서의 의도를 더욱 명확하게 하기 위해 이러한 용어 중 일부를 정의합니다.
Worker Service 템플릿은 .NET CLI 및 Visual Studio에서 사용할 수 있습니다. 자세한 내용은 .NET CLI, dotnet new worker
- 템플릿을 참조하세요. 템플릿은 Program
및 Worker
클래스로 구성됩니다.
using App.WorkerService;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<Worker>();
IHost host = builder.Build();
host.Run();
앞의 Program
클래스는 다음과 같습니다.
Worker
(을)를 등록합니다.Run
을 앱을 실행하는 host
인스턴스에서 호출합니다.작업자 템플릿은 기본적으로 GC(서버 가비지 수집)를 사용하도록 설정하지 않습니다. 그 필요성을 결정하는 데 중요한 역할을 하는 여러 요소가 있기 때문입니다. 장기 실행 서비스가 필요한 모든 시나리오는 이 기본값의 성능 영향을 고려해야 합니다. 서버 GC를 사용하도록 설정하려면 프로젝트 파일에 ServerGarbageCollection
노드를 추가합니다.
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>
절충 및 고려 사항
사용 | 사용 안 함 |
---|---|
효율적인 메모리 관리: 메모리 누수 방지 및 리소스 사용 최적화를 위해 사용되지 않는 메모리를 자동으로 회수합니다. | 실시간 성능 향상: 대기 시간에 민감한 애플리케이션에서 가비지 수집으로 인한 잠재적 일시 중지 또는 중단을 방지합니다. |
장기 안정성: 오랜 기간 동안 메모리를 관리하여 장기 실행 서비스에서 안정적인 성능을 유지하는 데 도움이 됩니다. | 리소스 효율성: 리소스가 제한된 환경에서 CPU 및 메모리 리소스를 절약할 수 있습니다. |
유지 관리 감소: 수동 메모리 관리의 필요성을 최소화하여 유지 관리를 간소화합니다. | 수동 메모리 제어: 특수 애플리케이션에 대한 메모리에 대한 세분화된 제어를 제공합니다. |
예측 가능한 동작: 일관되고 예측 가능한 애플리케이션 동작에 기여합니다. | 단기 프로세스에 적합: 단기 또는 임시 프로세스에 대한 가비지 수집 오버헤드를 최소화합니다. |
성능 고려 사항에 대한 자세한 내용은 Server GC를 참조하세요. 서버 GC를 구성하는 방법에 대한 자세한 내용은 Server GC 구성 예제를 참조하세요.
Worker
의 경우 템플릿은 간단한 구현을 제공합니다.
namespace App.WorkerService;
public sealed class Worker(ILogger<Worker> logger) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1_000, stoppingToken);
}
}
}
앞의 Worker
클래스는 IHostedService를 구현하는 BackgroundService의 하위 클래스입니다. BackgroundService는 abstract class
이며 BackgroundService.ExecuteAsync(CancellationToken)을 구현하려면 하위 클래스가 필요합니다. 템플릿 구현에서 ExecuteAsync
(은)는 초당 한 번씩 반복되며 프로세스가 취소하라는 신호를 표시할 때까지 현재 날짜 및 시간을 기록합니다.
작업자 템플릿은 다음 프로젝트 파일 Sdk
(을)를 사용합니다.
<Project Sdk="Microsoft.NET.Sdk.Worker">
자세한 내용은 .NET 프로젝트 SDK를 참조하세요.
작업자 템플릿을 기반으로 하는 앱은 Microsoft.NET.Sdk.Worker
SDK를 사용하며 Microsoft.Extensions.Hosting 패키지에 대한 명시적 패키지 참조가 있습니다.
대부분의 최신 .NET 워크로드에서는 컨테이너가 실행 가능한 옵션입니다. Visual Studio의 작업자 템플릿에서 장기 실행 서비스를 만들 때 Docker 지원으로 옵트인할 수 있습니다. 이렇게 하면 .NET 앱을 컨테이너화하는 Dockerfile이 만들어집니다. Dockerfile은 이미지를 빌드하기 위한 지침 세트입니다. .NET 앱의 경우 Dockerfile은 일반적으로 솔루션 파일 옆에 있는 디렉터리 루트에 있습니다.
# See https://aka.ms/containerfastmode to understand how Visual Studio uses this
# Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/runtime:8.0@sha256:e6b552fd7a0302e4db30661b16537f7efcdc0b67790a47dbf67a5e798582d3a5 AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:8.0@sha256:35792ea4ad1db051981f62b313f1be3b46b1f45cadbaa3c288cd0d3056eefb83 AS build
WORKDIR /src
COPY ["background-service/App.WorkerService.csproj", "background-service/"]
RUN dotnet restore "background-service/App.WorkerService.csproj"
COPY . .
WORKDIR "/src/background-service"
RUN dotnet build "App.WorkerService.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "App.WorkerService.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "App.WorkerService.dll"]
위의 Dockerfile 단계는 다음과 같습니다.
mcr.microsoft.com/dotnet/runtime:8.0
의 기본 이미지를 별칭 base
로 설정합니다.mcr.microsoft.com/dotnet/sdk:8.0
이미지에서 별칭 build
를 설정합니다.dotnet publish
명령을 사용하여 게시됩니다.mcr.microsoft.com/dotnet/runtime:8.0
(별칭 base
)에서 .NET SDK 이미지를 릴레이합니다.dotnet App.BackgroundService.dll
에 위임하는 진입점을 정의합니다.팁
mcr.microsoft.com
의 MCR은 “Microsoft Container Registry”의 약자이며 Microsoft가 배포하는 공식 Docker 허브의 컨테이너 카탈로그입니다. Microsoft, 컨테이너 카탈로그 배포 문서에서 추가 세부 정보를 확인하세요.
Docker를 .NET 작업자 서비스에 대한 배포 전략으로 대상으로 지정하는 경우 프로젝트 파일에 몇 가지 고려 사항이 있습니다.
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<RootNamespace>App.WorkerService</RootNamespace>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
</ItemGroup>
</Project>
위의 프로젝트 파일에서 <DockerDefaultTargetOS>
요소는 Linux
를 해당 대상으로 지정합니다. Windows 컨테이너를 대상으로 지정하려면 Windows
를 대신 사용합니다. 템플릿에서 Docker 지원을 선택하면 Microsoft.VisualStudio.Azure.Containers.Tools.Targets
NuGet 패키지가 패키지 참조로 자동으로 추가됩니다.
.NET을 사용한 Docker에 대한 자세한 내용은 자습서: .NET 앱 컨테이너화를 참조하세요. Azure에 배포하는 자세한 내용은 자습서: Azure에 Worker Service 배포를 참조하세요.
중요
작업자 템플릿을 사용하여 사용자 비밀을 활용하려면 Microsoft.Extensions.Configuration.UserSecrets
NuGet 패키지를 명시적으로 참조해야 합니다.
IHostedService 인터페이스는 다음 두 가지 메서드를 정의합니다.
이러한 두 메서드는 수명 주기 메서드 역할을 합니다. 호스트 시작 및 중지 이벤트 중에 각각 호출됩니다.
참고
StartAsync 또는 StopAsync 메서드를 재정의하는 경우 await
및 base
클래스 메서드를 호출하여 서비스가 제대로 시작 및/또는 종료되도록 해야 합니다.
중요
인터페이스는 AddHostedService<THostedService>(IServiceCollection) 확장 메서드에서 제네릭 형식 매개 변수 제약 조건으로 사용됩니다. 즉, 구현만 허용됩니다. 제공된 BackgroundService를 하위 클래스와 함께 사용하거나 사용자 고유 항목으로 완전히 구현할 수 있습니다.
대부분의 일반적인 시나리오에서는 호스트된 서비스의 완료를 명시적으로 알릴 필요가 없습니다. 호스트가 서비스를 시작하면 호스트가 중지될 때까지 실행되도록 설계되었습니다. 그러나 일부 시나리오에서는 서비스가 완료될 때 전체 호스트 애플리케이션의 완료를 신호로 표시해야 할 수 있습니다. 완료를 알리려면 다음 Worker
클래스를 고려합니다.
namespace App.SignalCompletionService;
public sealed class Worker(
IHostApplicationLifetime hostApplicationLifetime,
ILogger<Worker> logger) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// TODO: implement single execution logic here.
logger.LogInformation(
"Worker running at: {Time}", DateTimeOffset.Now);
await Task.Delay(1_000, stoppingToken);
// When completed, the entire app host will stop.
hostApplicationLifetime.StopApplication();
}
}
앞의 코드에서 ExecuteAsync
메서드는 반복되지 않으며 완료되면 IHostApplicationLifetime.StopApplication()(을)를 호출합니다.
중요
그러면 호스트가 중지되어야 한다는 신호가 표시되고, StopApplication
대한 이 호출이 없으면 호스트가 무기한으로 실행됩니다.
자세한 내용은 다음을 참조하세요.
.NET 피드백
.NET은(는) 오픈 소스 프로젝트입니다. 다음 링크를 선택하여 피드백을 제공해 주세요.
학습
모듈
ASP.NET Core에서 종속성 주입을 사용하여 서비스 구성 - Training
ASP.NET Core 앱에서 종속성 주입을 파악하고 구현합니다. ASP.NET Core의 기본 제공 서비스 컨테이너를 사용하여 종속성을 관리합니다. 서비스 컨테이너에 서비스를 등록합니다.