.NET Aspire Nedir? Neden Kullanılır?

Github ProjeAyazDuru.Samples.Aspire

.NET Aspire Nedir?

.NET Aspire, .NET uygulamaları için bulut-native uygulama orkestrasyonu sağlayan bir geliştirme platformudur.

Bulut tabanlı uygulamalar geliştirmek isteyen .NET geliştiricileri için geliştirme ortamını kurmak, bağımlılıkları yönetmek, mikro servisleri entegre etmek genellikle zahmetlidir. İşte tam bu noktada .NET Aspire devreye giriyor.

Microsoft tarafından 2024’te duyurulan Aspire, modern .NET uygulamalarını hızlıca geliştirmek, çalıştırmak ve test etmek için hazırlanmış bir orkestrasyon ve geliştirme platformudur.

Aspire; mikro servisler, veritabanları, mesajlaşma kuyrukları, cache sistemleri gibi bileşenleri kolayca ayağa kaldırmanıza ve entegre etmenize yardımcı olur.

Öne çıkan özellikleri:

  • Hızlı başlangıç: Sıfırdan mikro servis projesi kurarken gerekli bağımlılıkları otomatik ekler.

  • Entegrasyon kolaylığı: RabbitMQ, Kafka, PostgreSQL, Redis gibi servisler için hazır bileşenler sağlar.

  • Gözlemlenebilirlik (Observability): Uygulamanızın log, trace ve metric verilerini tek noktadan izleyebilirsiniz.

  • Docker uyumluluğu: Servisleri containerize etmek ve docker-compose ile yönetmek çok kolaydır.

  • Bulut hazır: Azure, AWS veya kendi on-premise ortamınıza kolayca taşınabilir.

.NET Aspire Neden Kullanmalıyım?

Mikro servis dünyasında geliştiriciler şu problemlerle sık karşılaşıyor:

  • Her servisin ayrı bağımlılığı (DB, message broker vs.)

  • Konfigürasyon karmaşası

  • Lokal geliştirme ortamını prodüksiyona benzetememe

  • Servisler arası iletişimi test etmek için zahmetli kurulumlar

Aspire bu sorunlara çözüm getirir:

  • Tek bir Aspire.Apphost projesi üzerinden tüm bağımlılıkları ayağa kaldırabilirsiniz.

  • Servislerinizi tek tıkla çalıştırabilir ve gözlemleyebilirsiniz.

  • Takım içi geliştirmeyi kolaylaştırır: "Works on my machine" problemini azaltır.

Özetle: Aspire = .NET dünyasının Docker Compose + Orkestrasyon + Observability birleşimi.

İncelemeye Başlayalım

İlk olarak Visual Studio > Create New Project ile yeni hazır bir proje açalım.

Aşağıda resimde gördüğümüz gibi bir proje yapısının oluşması gerekiyor.

AyazDuru.Samples.Aspire.AppHost projesindeki AppHost.cs

// Dağıtık uygulama için bir builder oluşturuluyor.
var builder = DistributedApplication.CreateBuilder(args);

// Redis önbellek servisi ekleniyor.
var cache = builder.AddRedis("cache");

// API servis projesi ekleniyor ve sağlık kontrolü endpoint'i tanımlanıyor.
var apiService = builder.AddProject<Projects.AyazDuru_Samples_Aspire_ApiService>("apiservice")
    .WithHttpHealthCheck("/health");

// Web frontend projesi ekleniyor, dış HTTP endpoint'leri açılıyor ve bağımlılıklar tanımlanıyor.
builder.AddProject<Projects.AyazDuru_Samples_Aspire_Web>("webfrontend")
    .WithExternalHttpEndpoints() // Dışarıya açık HTTP endpoint'leri ekleniyor.
    .WithHttpHealthCheck("/health") // Sağlık kontrolü endpoint'i ekleniyor.
    .WithReference(cache) // Redis önbellek servisine referans veriliyor.
    .WaitFor(cache) // Redis servisi hazır olana kadar bekleniyor.
    .WithReference(apiService) // API servisine referans veriliyor.
    .WaitFor(apiService); // API servisi hazır olana kadar bekleniyor.

// Uygulama başlatılıyor.
builder.Build().Run();

AyazDuru.Samples.Aspire.ServiceDefaults projesindeki Extensions.cs

// Bu sınıf, .NET Aspire projelerinde ortak olarak kullanılan servisleri ekler.
// Servis keşfi, dayanıklılık, sağlık kontrolleri ve OpenTelemetry gibi modern bulut uygulamalarında kritik olan özellikleri kolayca projeye dahil eder.
public static class Extensions
{
    private const string HealthEndpointPath = "/health";
    private const string AlivenessEndpointPath = "/alive";

    // .NET Aspire servis varsayılanlarını ekler: servis keşfi, dayanıklılık, sağlık kontrolleri ve telemetri.
    public static TBuilder AddServiceDefaults<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
    {
        builder.ConfigureOpenTelemetry(); // OpenTelemetry ile izleme ve metrik toplama

        builder.AddDefaultHealthChecks(); // Sağlık kontrolleri ekleniyor

        builder.Services.AddServiceDiscovery(); // Servis keşfi (Service Discovery) ekleniyor

        builder.Services.ConfigureHttpClientDefaults(http =>
        {
            // HTTP isteklerinde dayanıklılık (resilience) varsayılan olarak aktif
            http.AddStandardResilienceHandler();

            // HTTP isteklerinde servis keşfi varsayılan olarak aktif
            http.AddServiceDiscovery();
        });

        // Servis keşfinde izin verilen protokolleri kısıtlamak için aşağıdaki satırı açabilirsiniz.
        // builder.Services.Configure<ServiceDiscoveryOptions>(options =>
        // {
        //     options.AllowedSchemes = ["https"];
        // });

        return builder;
    }

    // OpenTelemetry yapılandırması: İzleme ve metrik toplama için kullanılır.
    public static TBuilder ConfigureOpenTelemetry<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
    {
        builder.Logging.AddOpenTelemetry(logging =>
        {
            logging.IncludeFormattedMessage = true;
            logging.IncludeScopes = true;
        });

        builder.Services.AddOpenTelemetry()
            .WithMetrics(metrics =>
            {
                metrics.AddAspNetCoreInstrumentation() // ASP.NET Core metrikleri
                    .AddHttpClientInstrumentation() // HTTP istemci metrikleri
                    .AddRuntimeInstrumentation(); // .NET çalışma zamanı metrikleri
            })
            .WithTracing(tracing =>
            {
                tracing.AddSource(builder.Environment.ApplicationName)
                    .AddAspNetCoreInstrumentation(tracing =>
                        // Sağlık kontrolü istekleri izlemeye dahil edilmez
                        tracing.Filter = context =>
                            !context.Request.Path.StartsWithSegments(HealthEndpointPath)
                            && !context.Request.Path.StartsWithSegments(AlivenessEndpointPath)
                    )
                    // gRPC istemci izleme için aşağıdaki satırı açabilirsiniz
                    //.AddGrpcClientInstrumentation()
                    .AddHttpClientInstrumentation();
            });

        builder.AddOpenTelemetryExporters(); // Telemetri verisini dışa aktaran eklentiler

        return builder;
    }

    // OpenTelemetry dışa aktarıcılarını ekler (ör. OTLP veya Azure Monitor)
    private static TBuilder AddOpenTelemetryExporters<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
    {
        var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);

        if (useOtlpExporter)
        {
            builder.Services.AddOpenTelemetry().UseOtlpExporter(); // OTLP ile telemetri verisi dışa aktarılır
        }

        // Azure Monitor dışa aktarıcıyı eklemek için aşağıdaki satırı açabilirsiniz
        //if (!string.IsNullOrEmpty(builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]))
        //{
        //    builder.Services.AddOpenTelemetry()
        //       .UseAzureMonitor();
        //}

        return builder;
    }

    // Varsayılan sağlık kontrollerini ekler
    public static TBuilder AddDefaultHealthChecks<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
    {
        builder.Services.AddHealthChecks()
            // Uygulamanın canlı (responsive) olduğunu doğrulayan varsayılan kontrol
            .AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]);

        return builder;
    }

    // Varsayılan sağlık kontrolü uç noktalarını haritalar
    public static WebApplication MapDefaultEndpoints(this WebApplication app)
    {
        // Sağlık kontrolü uç noktalarını geliştirme ortamında eklemek güvenlik açısından önemlidir.
        // Detaylar için: https://aka.ms/dotnet/aspire/healthchecks
        if (app.Environment.IsDevelopment())
        {
            // Tüm sağlık kontrolleri geçerse uygulama trafiğe hazır kabul edilir
            app.MapHealthChecks(HealthEndpointPath);

            // Sadece "live" etiketiyle işaretlenen sağlık kontrolleri geçerse uygulama canlı kabul edilir
            app.MapHealthChecks(AlivenessEndpointPath, new HealthCheckOptions
            {
                Predicate = r => r.Tags.Contains("live")
            });
        }

        return app;
    }

AyazDuru.Samples.Aspire.AppHost projesini Visual Studio üzerinden başlattığımızda, aşağıda gördüğünüz gibi ilk olarak Redis imajını indirip Docker Dekstop üzerinden başlattı. Daha sonra API ve Web projelerini tek tek başlattı.

Kısaca .NET Aspire anlatmak istedim. Umarım kafanızdaki bazı sorulara cevap verebilmişimdir.

Sağlıcakla kalın.

Yorumlar kapalı