다음을 통해 공유


사용자 지정 .NET Aspireclient 통합 만들기

이 문서는 사용자 지정 .NET.NET Aspire 호스팅 통합 문서의 연속입니다. MailKit 사용하여 전자 메일을 보내는 .NET Aspireclient 통합을 만드는 방법을 안내합니다. 이 통합은 이전에 빌드한 뉴스레터 앱에 추가됩니다. 이전 예제에서는 client 통합 만들기를 생략하고 대신 기존 .NETSmtpClient의존했습니다. 이메일을 보내는 데에는 MailKit의 SmtpClient을 사용하는 것이 공식 .NETSmtpClient보다 더 좋습니다. 더 최신이고 더 많은 기능/프로토콜을 지원하기 때문입니다. 자세한 내용은 .NET SmtpClient: 설명을 참조하세요.

필수 구성 요소

따라오고 있다면, 사용자 지정 .NET.NET Aspire 호스팅 통합 문서 단계에서 뉴스레터 앱을 갖추고 있어야 합니다.

이 문서는 기존 .NET.NET Aspire 통합에서 영감을 받아 팀의 공식 지침을 기반으로 합니다. 안내가 달라지는 곳이 있으며 차이점의 추론을 이해하는 것이 중요합니다. 자세한 내용은 통합 요구 사항을 참조하세요.

통합을 위한 라이브러리 만들기

통합은 NuGet 패키지로 제공되지만 이 예제에서는 NuGet 패키지를 게시하는 것이 이 문서의 범위를 벗어납니다. 대신 통합이 포함된 클래스 라이브러리 프로젝트를 만들고 프로젝트로 참조합니다. .NET Aspire 통합 패키지는 MailKit와 같은 client 라이브러리를 감싸고, 실제 운영에 적합한 원격 분석, 건강 상태 검사, 구성 가능성 및 테스트 가능성을 제공하기 위한 것입니다. 먼저 새 클래스 라이브러리 프로젝트를 만들어 보겠습니다.

  1. 새 클래스 라이브러리 프로젝트를 MailKit.Client이라는 이름으로 이전 문서의 MailDevResource.sln와 동일한 디렉토리에 생성합니다.

    dotnet new classlib -o MailKit.Client
    
  2. 솔루션에 프로젝트를 추가합니다.

    dotnet sln ./MailDevResource.sln add MailKit.Client/MailKit.Client.csproj
    

다음 단계는 통합에 의존하는 모든 NuGet 패키지를 추가하는 것입니다. .NET CLI에서 각 패키지를 하나씩 추가하는 대신 다음 XML을 복사하여 MailKit에 붙여넣는 것이 더 쉬울 수 있습니다. .csproj 파일을Client.

<ItemGroup>
  <PackageReference Include="MailKit" Version="4.9.0" />
  <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.0" />
  <PackageReference Include="Microsoft.Extensions.Resilience" Version="9.0.0" />
  <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.0" />
  <PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="9.0.0" />
  <PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.10.0" />
</ItemGroup>

통합 설정 정의

.NET Aspire 통합을 만들 때, 매핑 대상인 client 라이브러리를 이해하는 것이 중요합니다. MailKit를 사용하면 Simple Mail Transfer Protocol(SMTP) server에 연결하는 데 필요한 구성 설정을 이해해야 합니다. 그러나 라이브러리가 상태 검사, 추적메트릭을 지원하는지 이해하는 것 또한 중요합니다. MailKit는 Telemetry.SmtpClient 클래스을 통해 추적메트릭을 지원합니다. 상태 검사를 추가할 때 가능한 경우 설정된 상태 검사 또는 기존 상태 검사를 사용해야 합니다. 그렇지 않으면 통합에서 사용자 고유의 구현을 고려할 수 있습니다. MailKitClientSettings.cs파일의 MailKit.Client 프로젝트에 다음 코드를 추가합니다.

using System.Data.Common;

namespace MailKit.Client;

/// <summary>
/// Provides the client configuration settings for connecting MailKit to an SMTP server.
/// </summary>
public sealed class MailKitClientSettings
{
    internal const string DefaultConfigSectionName = "MailKit:Client";

    /// <summary>
    /// Gets or sets the SMTP server <see cref="Uri"/>.
    /// </summary>
    /// <value>
    /// The default value is <see langword="null"/>.
    /// </value>
    public Uri? Endpoint { get; set; }

    /// <summary>
    /// Gets or sets a boolean value that indicates whether the database health check is disabled or not.
    /// </summary>
    /// <value>
    /// The default value is <see langword="false"/>.
    /// </value>
    public bool DisableHealthChecks { get; set; }

    /// <summary>
    /// Gets or sets a boolean value that indicates whether the OpenTelemetry tracing is disabled or not.
    /// </summary>
    /// <value>
    /// The default value is <see langword="false"/>.
    /// </value>
    public bool DisableTracing { get; set; }

    /// <summary>
    /// Gets or sets a boolean value that indicates whether the OpenTelemetry metrics are disabled or not.
    /// </summary>
    /// <value>
    /// The default value is <see langword="false"/>.
    /// </value>
    public bool DisableMetrics { get; set; }

    internal void ParseConnectionString(string? connectionString)
    {
        if (string.IsNullOrWhiteSpace(connectionString))
        {
            throw new InvalidOperationException($"""
                    ConnectionString is missing.
                    It should be provided in 'ConnectionStrings:<connectionName>'
                    or '{DefaultConfigSectionName}:Endpoint' key.'
                    configuration section.
                    """);
        }

        if (Uri.TryCreate(connectionString, UriKind.Absolute, out var uri))
        {
            Endpoint = uri;
        }
        else
        {
            var builder = new DbConnectionStringBuilder
            {
                ConnectionString = connectionString
            };
            
            if (builder.TryGetValue("Endpoint", out var endpoint) is false)
            {
                throw new InvalidOperationException($"""
                        The 'ConnectionStrings:<connectionName>' (or 'Endpoint' key in
                        '{DefaultConfigSectionName}') is missing.
                        """);
            }

            if (Uri.TryCreate(endpoint.ToString(), UriKind.Absolute, out uri) is false)
            {
                throw new InvalidOperationException($"""
                        The 'ConnectionStrings:<connectionName>' (or 'Endpoint' key in
                        '{DefaultConfigSectionName}') isn't a valid URI.
                        """);
            }

            Endpoint = uri;
        }
    }
}

위의 코드는 다음을 사용하여 MailKitClientSettings 클래스를 정의합니다.

  • SMTP server에 대한 연결 문자열을 나타내는 속성 Endpoint입니다.
  • 상태 검사를 사용할 수 있는지 여부를 결정하는 DisableHealthChecks 속성입니다.
  • 추적을 사용할 수 있는지 여부를 결정하는 DisableTracing 속성입니다.
  • 메트릭을 사용할지 여부를 결정하는 DisableMetrics 속성입니다.

연결 문자열 논리 구문 분석

설정 클래스에는 연결 문자열을 유효한 Uri구문 분석하는 ParseConnectionString 메서드도 포함되어 있습니다. 구성은 다음 형식으로 제공되어야 합니다.

  • ConnectionStrings:<connectionName>: SMTP server대한 연결 문자열입니다.
  • MailKit:Client:ConnectionString: SMTP server대한 연결 문자열입니다.

둘 중 하나의 값도 제공되지 않으면 예외가 발생합니다.

client 기능 공개

.NET Aspire 통합의 목표는 종속성 주입을 통해 기본 client 라이브러리를 소비자에게 공개하는 것입니다. MailKit과 이 예제에서는 SmtpClient 클래스를 공개할 필요가 있습니다. 기능을 래핑하는 것이 아니라 구성 설정을 SmtpClient 클래스에 매핑합니다. 통합에 대한 표준 및 키 서비스 등록을 모두 노출하는 것이 일반적입니다. 표준 등록은 서비스의 인스턴스가 하나뿐인 경우 사용되며, 서비스의 인스턴스가 여러 개 있을 때 키 서비스 등록이 사용됩니다. 경우에 따라 동일한 형식의 여러 등록을 수행하려면 팩터리 패턴을 사용합니다. MailKitClientFactory.cs파일의 MailKit.Client 프로젝트에 다음 코드를 추가합니다.

using MailKit.Net.Smtp;

namespace MailKit.Client;

/// <summary>
/// A factory for creating <see cref="ISmtpClient"/> instances
/// given a <paramref name="smtpUri"/> (and optional <paramref name="credentials"/>).
/// </summary>
/// <param name="settings">
/// The <see cref="MailKitClientSettings"/> settings for the SMTP server
/// </param>
public sealed class MailKitClientFactory(MailKitClientSettings settings) : IDisposable
{
    private readonly SemaphoreSlim _semaphore = new(1, 1);

    private SmtpClient? _client;

    /// <summary>
    /// Gets an <see cref="ISmtpClient"/> instance in the connected state
    /// (and that's been authenticated if configured).
    /// </summary>
    /// <param name="cancellationToken">Used to abort client creation and connection.</param>
    /// <returns>A connected (and authenticated) <see cref="ISmtpClient"/> instance.</returns>
    /// <remarks>
    /// Since both the connection and authentication are considered expensive operations,
    /// the <see cref="ISmtpClient"/> returned is intended to be used for the duration of a request
    /// (registered as 'Scoped') and is automatically disposed of.
    /// </remarks>
    public async Task<ISmtpClient> GetSmtpClientAsync(
        CancellationToken cancellationToken = default)
    {
        await _semaphore.WaitAsync(cancellationToken);

        try
        {
            if (_client is null)
            {
                _client = new SmtpClient();

                await _client.ConnectAsync(settings.Endpoint, cancellationToken)
                             .ConfigureAwait(false);
            }
        }
        finally
        {
            _semaphore.Release();
        }       

        return _client;
    }

    public void Dispose()
    {
        _client?.Dispose();
        _semaphore.Dispose();
    }
}

MailKitClientFactory 클래스는 구성 설정에 따라 ISmtpClient 인스턴스를 만드는 팩터리입니다. 구성된 SMTP server에 대한 활성 연결을 가진 ISmtpClient 구현을 반환하는 것이 책임입니다. 다음으로, 소비자가 이 팩터리를 종속성 주입 컨테이너에 등록할 수 있도록 기능을 제공해야 합니다. MailKitExtensions.cs파일의 MailKit.Client 프로젝트에 다음 코드를 추가합니다.

using MailKit;
using MailKit.Client;
using MailKit.Net.Smtp;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Microsoft.Extensions.Hosting;

/// <summary>
/// Provides extension methods for registering a <see cref="SmtpClient"/> as a
/// scoped-lifetime service in the services provided by the <see cref="IHostApplicationBuilder"/>.
/// </summary>
public static class MailKitExtensions
{
    /// <summary>
    /// Registers 'Scoped' <see cref="MailKitClientFactory" /> for creating
    /// connected <see cref="SmtpClient"/> instance for sending emails.
    /// </summary>
    /// <param name="builder">
    /// The <see cref="IHostApplicationBuilder" /> to read config from and add services to.
    /// </param>
    /// <param name="connectionName">
    /// A name used to retrieve the connection string from the ConnectionStrings configuration section.
    /// </param>
    /// <param name="configureSettings">
    /// An optional delegate that can be used for customizing options.
    /// It's invoked after the settings are read from the configuration.
    /// </param>
    public static void AddMailKitClient(
        this IHostApplicationBuilder builder,
        string connectionName,
        Action<MailKitClientSettings>? configureSettings = null) =>
        AddMailKitClient(
            builder,
            MailKitClientSettings.DefaultConfigSectionName,
            configureSettings,
            connectionName,
            serviceKey: null);

    /// <summary>
    /// Registers 'Scoped' <see cref="MailKitClientFactory" /> for creating
    /// connected <see cref="SmtpClient"/> instance for sending emails.
    /// </summary>
    /// <param name="builder">
    /// The <see cref="IHostApplicationBuilder" /> to read config from and add services to.
    /// </param>
    /// <param name="name">
    /// The name of the component, which is used as the <see cref="ServiceDescriptor.ServiceKey"/> of the
    /// service and also to retrieve the connection string from the ConnectionStrings configuration section.
    /// </param>
    /// <param name="configureSettings">
    /// An optional method that can be used for customizing options. It's invoked after the settings are
    /// read from the configuration.
    /// </param>
    public static void AddKeyedMailKitClient(
        this IHostApplicationBuilder builder,
        string name,
        Action<MailKitClientSettings>? configureSettings = null)
    {
        ArgumentNullException.ThrowIfNull(name);

        AddMailKitClient(
            builder,
            $"{MailKitClientSettings.DefaultConfigSectionName}:{name}",
            configureSettings,
            connectionName: name,
            serviceKey: name);
    }

    private static void AddMailKitClient(
        this IHostApplicationBuilder builder,
        string configurationSectionName,
        Action<MailKitClientSettings>? configureSettings,
        string connectionName,
        object? serviceKey)
    {
        ArgumentNullException.ThrowIfNull(builder);

        var settings = new MailKitClientSettings();

        builder.Configuration
               .GetSection(configurationSectionName)
               .Bind(settings);

        if (builder.Configuration.GetConnectionString(connectionName) is string connectionString)
        {
            settings.ParseConnectionString(connectionString);
        }

        configureSettings?.Invoke(settings);

        if (serviceKey is null)
        {
            builder.Services.AddScoped(CreateMailKitClientFactory);
        }
        else
        {
            builder.Services.AddKeyedScoped(serviceKey, (sp, key) => CreateMailKitClientFactory(sp));
        }

        MailKitClientFactory CreateMailKitClientFactory(IServiceProvider _)
        {
            return new MailKitClientFactory(settings);
        }

        if (settings.DisableHealthChecks is false)
        {
            builder.Services.AddHealthChecks()
                .AddCheck<MailKitHealthCheck>(
                    name: serviceKey is null ? "MailKit" : $"MailKit_{connectionName}",
                    failureStatus: default,
                    tags: []);
        }

        if (settings.DisableTracing is false)
        {
            builder.Services.AddOpenTelemetry()
                .WithTracing(
                    traceBuilder => traceBuilder.AddSource(
                        Telemetry.SmtpClient.ActivitySourceName));
        }

        if (settings.DisableMetrics is false)
        {
            // Required by MailKit to enable metrics
            Telemetry.SmtpClient.Configure();

            builder.Services.AddOpenTelemetry()
                .WithMetrics(
                    metricsBuilder => metricsBuilder.AddMeter(
                        Telemetry.SmtpClient.MeterName));
        }
    }
}

앞의 코드는 IHostApplicationBuilder 형식에 두 개의 확장 메서드를 추가합니다. 하나는 MailKit의 표준 등록용이고 다른 하나는 MailKit의 키 등록용입니다.

조언

.NET .NET Aspire 통합에 대한 확장 메서드는 IHostApplicationBuilder 형식을 확장하고 <MeaningfulName> 추가하는 형식 또는 기능인 Add<MeaningfulName> 명명 규칙을 따라야 합니다. 이 문서에서는 AddMailKitClient 확장 메서드를 사용하여 MailKit client추가합니다. 공식 지침에 따르면 전체 MailKit 라이브러리가 아닌 SmtpClient만 등록하기 때문에 AddMailKitClient대신 AddMailKitSmtpClient을 사용하는 것이 더 적합할 수 있습니다.

두 확장 기능은 모두 궁극적으로 프라이빗 AddMailKitClient 메서드를 사용하여 MailKitClientFactory을(를) 범위 서비스로 종속성 주입 컨테이너에 등록합니다. MailKitClientFactory 범위가 지정된 서비스로 등록하는 이유는 연결 작업이 비용이 많이 드는 것으로 간주되어 가능한 경우 동일한 범위 내에서 다시 사용되어야 했기 때문입니다. 즉, 단일 요청의 경우 동일한 ISmtpClient 인스턴스를 사용해야 합니다. 공장은 생성한 SmtpClient 인스턴스를 보유하고 처분합니다.

환경 설정 연결

AddMailKitClient 메서드의 프라이빗 구현이 수행하는 첫 번째 작업 중 하나는 구성 설정을 MailKitClientSettings 클래스에 바인딩하는 것입니다. 설정 클래스가 인스턴스화된 다음 구성의 특정 섹션을 사용하여 Bind 호출됩니다. 그런 다음 선택적 configureSettings 대리자가 현재 설정으로 호출됩니다. 이렇게 하면 소비자가 설정을 추가로 구성하여 수동 코드 설정이 구성 설정보다 우선시되도록 할 수 있습니다. 그 후, serviceKey 값이 제공되었는지 여부에 따라 MailKitClientFactory이 종속성 주입 컨테이너에 표준 서비스 또는 키 지정 서비스로 등록되어야 합니다.

중요하다

서비스를 등록할 때 implementationFactory 오버로드가 호출되는 것은 의도적인 일입니다. 구성이 잘못되면 CreateMailKitClientFactory 메서드가 예외를 발생시킵니다. 이렇게 하면 MailKitClientFactory의 생성이 필요할 때까지 미뤄지고, 로깅이 가능해지기 전에 앱이 오류가 발생하지 않도록 방지합니다.

상태 검사 및 원격 분석의 등록 사항은 다음 섹션에서 좀 더 구체적으로 설명되어 있습니다.

건강 상태 검사 추가

건강 상태 검사는 통합의 건강 상태를 모니터링하는 방법입니다. MailKit을 사용하면 SMTP server 대한 연결이 정상인지 확인할 수 있습니다. MailKitHealthCheck.cs파일의 MailKit.Client 프로젝트에 다음 코드를 추가합니다.

using Microsoft.Extensions.Diagnostics.HealthChecks;

namespace MailKit.Client;

internal sealed class MailKitHealthCheck(MailKitClientFactory factory) : IHealthCheck
{
    public async Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default)
    {
        try
        {
            // The factory connects (and authenticates).
            _ = await factory.GetSmtpClientAsync(cancellationToken);

            return HealthCheckResult.Healthy();
        }
        catch (Exception ex)
        {
            return HealthCheckResult.Unhealthy(exception: ex);
        }
    }
}

위의 상태 검사 구현은 다음과 같습니다.

  • IHealthCheck 인터페이스를 구현합니다.
  • MailKitClientFactory 기본 생성자 매개 변수로 허용합니다.
  • 다음 방식으로 CheckHealthAsync 메서드를 충족합니다.
    • factory에서 ISmtpClient 인스턴스를 가져오려고 시도합니다. 성공하면 HealthCheckResult.Healthy반환됩니다.
    • 예외가 발생하면 HealthCheckResult.Unhealthy을 반환합니다.

이전에 MailKitClientFactory등록에서 공유한 것처럼, MailKitHealthCheckIHeathChecksBuilder에 조건부로 등록되었습니다.

if (settings.DisableHealthChecks is false)
{
    builder.Services.AddHealthChecks()
        .AddCheck<MailKitHealthCheck>(
            name: serviceKey is null ? "MailKit" : $"MailKit_{connectionName}",
            failureStatus: default,
            tags: []);
}

소비자는 구성에서 DisableHealthChecks 속성을 true으로 설정하여 상태 검사를 생략하도록 선택할 수 있습니다. 통합의 일반적인 패턴은 선택적 기능을 가지는 것이며 .NET.NET Aspire 통합은 이러한 유형의 구성을 강력하게 권장합니다. 상태 검사 및 사용자 인터페이스를 포함하는 작업 샘플에 대한 자세한 내용은 .NET AspireASP.NET Core HealthChecksUI 샘플참조하세요.

텔레메트리 연결

모범 사례로, MailKit client 라이브러리는 원격 분석를 제공합니다. .NET .NET Aspire에서는 이 원격 분석을 활용하여 .NET.NET Aspire 대시보드에 표시할 수 있습니다. 추적 및 메트릭이 활성화되었는지 여부에 따라, 원격 분석(telemetry)은 다음 코드 조각과 같이 설정됩니다.

if (settings.DisableTracing is false)
{
    builder.Services.AddOpenTelemetry()
        .WithTracing(
            traceBuilder => traceBuilder.AddSource(
                Telemetry.SmtpClient.ActivitySourceName));
}

if (settings.DisableMetrics is false)
{
    // Required by MailKit to enable metrics
    Telemetry.SmtpClient.Configure();

    builder.Services.AddOpenTelemetry()
        .WithMetrics(
            metricsBuilder => metricsBuilder.AddMeter(
                Telemetry.SmtpClient.MeterName));
}

뉴스레터 서비스 업데이트

통합 라이브러리를 만들면 이제 MailKit client사용하도록 뉴스레터 서비스를 업데이트할 수 있습니다. 첫 번째 단계는 MailKit.Client 프로젝트에 대한 참조를 추가하는 것입니다. MailKit를 추가합니다. MailDevResource.NewsletterService 프로젝트에 대한 .csproj 프로젝트 참조를Client.

dotnet add ./MailDevResource.NewsletterService/MailDevResource.NewsletterService.csproj reference MailKit.Client/MailKit.Client.csproj

다음으로, ServiceDefaults 프로젝트에 대한 참조를 추가합니다.

dotnet add ./MailDevResource.NewsletterService/MailDevResource.NewsletterService.csproj reference MailDevResource.ServiceDefaults/MailDevResource.ServiceDefaults.csproj

마지막 단계는 MailDevResource.NewsletterService 프로젝트의 기존 Program.cs 파일을 다음 C# 코드로 바꾸는 것입니다.

using System.Net.Mail;
using MailKit.Client;
using MailKit.Net.Smtp;
using MimeKit;

var builder = WebApplication.CreateBuilder(args);

builder.AddServiceDefaults();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// Add services to the container.
builder.AddMailKitClient("maildev");

var app = builder.Build();

app.MapDefaultEndpoints();

// Configure the HTTP request pipeline.

app.UseSwagger();
app.UseSwaggerUI();
app.UseHttpsRedirection();

app.MapPost("/subscribe",
    async (MailKitClientFactory factory, string email) =>
{
    ISmtpClient client = await factory.GetSmtpClientAsync();

    using var message = new MailMessage("newsletter@yourcompany.com", email)
    {
        Subject = "Welcome to our newsletter!",
        Body = "Thank you for subscribing to our newsletter!"
    };

    await client.SendAsync(MimeMessage.CreateFromMailMessage(message));
});

app.MapPost("/unsubscribe",
    async (MailKitClientFactory factory, string email) =>
{
    ISmtpClient client = await factory.GetSmtpClientAsync();

    using var message = new MailMessage("newsletter@yourcompany.com", email)
    {
        Subject = "You are unsubscribed from our newsletter!",
        Body = "Sorry to see you go. We hope you will come back soon!"
    };

    await client.SendAsync(MimeMessage.CreateFromMailMessage(message));
});

app.Run();

이전 코드에서 가장 주목할 만한 변경 내용은 다음과 같습니다.

  • 업데이트된 using 문서로 MailKit.Client, MailKit.Net.SmtpMimeKit 네임스페이스가 포함되었습니다.
  • 공식 .NETSmtpClient 등록을 AddMailKitClient 확장 메서드 호출로 대체하기.
  • /subscribe/unsubscribe 맵 게시 호출을 대신 MailKitClientFactory를 삽입하고, ISmtpClient 인스턴스를 사용하여 이메일을 보내도록 교체합니다.

샘플 실행

이제 MailKit client 통합을 만들고 이를 사용하도록 뉴스레터 서비스를 업데이트했으므로 샘플을 실행할 수 있습니다. IDE에서 F5 선택하거나 솔루션의 루트 디렉터리에서 dotnet run 실행하여 애플리케이션을 시작합니다. .NET.NET Aspire 대시보드표시됩니다.

.NET Aspire 대시보드: MailDev가 실행 중이며 뉴스레터 자원도 사용 중입니다.

애플리케이션이 실행되면 https://localhost:7251/swagger의 Swagger UI로 이동하여 /subscribe/unsubscribe 엔드포인트를 테스트하십시오. 아래쪽 화살표를 선택하여 엔드포인트를 확장합니다.

Swagger UI: 구독 엔드포인트

그런 다음 Try it out 단추를 선택합니다. 전자 메일 주소를 입력한 다음 Execute 단추를 선택합니다.

Swagger UI: 전자 메일 주소로 엔드포인트를 구독합니다.

여러 전자 메일 주소를 추가하려면 이 작업을 여러 번 반복합니다. MailDev 받은편지함에서 전송된 이메일을 확인해 보세요.

MailDev 여러 전자 메일이 있는 받은 편지함.

애플리케이션이 실행 중인 터미널 창에서 Ctrl+C 선택하거나 IDE에서 중지 단추를 선택하여 애플리케이션을 중지합니다.

MailKit 원격 분석 보기

MailKit client 라이브러리는 .NET Aspire 대시보드에서 볼 수 있는 테레메트리를 제공합니다. 원격 분석을 보려면 .NET.NET Aspire 대시보드로 https://localhost:7251이동하세요. newsletter 리소스를 선택하고 메트릭 페이지에서 원격 분석을 확인합니다.

.NET.NET Aspire 대시보드: MailKit 원격 분석.

Swagger UI를 다시 열고 /subscribe/unsubscribe 엔드포인트에 대한 몇 가지 요청을 합니다. 그런 다음, .NET.NET Aspire 대시보드로 돌아가서 newsletter 리소스를 선택합니다. mailkit.net.smtp.client.operation.count같은 mailkit.net.smtp 노드에서 메트릭을 선택합니다. MailKit client의 원격 분석을 확인해야 합니다.

.NET.NET Aspire 대시보드: MailKit의 작업 수 원격 분석.

요약

이 문서에서는 MailKit을 사용하여 전자 메일을 보내는 .NET.NET Aspire 통합을 만드는 방법을 알아보았습니다. 또한 이전에 빌드한 뉴스레터 앱에 이 통합을 통합하는 방법도 알아보았습니다. 종속성 주입을 통해 소비자에게 기본 client 라이브러리를 노출하는 등 .NET Aspire 통합의 핵심 원칙과 통합에 상태 검사 및 원격 분석을 추가하는 방법에 대해 알아보았습니다. MailKit client사용하도록 뉴스레터 서비스를 업데이트하는 방법도 알아보았습니다.

직접 고유한 .NET.NET Aspire 통합을 만드세요. 빌드하는 통합에 충분한 커뮤니티 가치가 있다고 생각되는 경우 다른 사용자가 사용할 NuGet 패키지로 게시하는 것이 좋습니다. 또한, 공식 .NET.NET Aspire 통합에 포함하기 위해 .NET AspireGitHub 리포지토리에 끌어오기 요청을 제출하는 것을 고려해 보세요.

다음 단계