Yazılım Mimarileri ve Tasarım Desenleri Üzerine

.NET 6 – WebApplication İle Middleware Pipeline’ını İnceleyelim

Merhaba,

Bu içeriğimizde .NET 6’da ki WebApplication nesnesinin arkasındaki koda bakacak, middleware ve endpointlerin nasıl yapılandırıldığına odaklanıyor olacağız.

Önceki .NET 6 – WebApplicationBuilder’ı İnceleyelim başlıklı makalede açıklandığı gibi uygulama yapılandırmasının yapıldığı yer çoğunlukla WebApplicationBuilder‘dır.

WebApplication ise üç ayrı işlev için operasyonel sorumluluk üstlenmektedir;

  1. IApplicationBuilder arayüzünü uyguladığı için middleware pipeline’ı burada şekillendirilip, yapılandırılmaktadır. Yani middleware şeması bu nesne üzerinden çıkarılmakta ve tetiklenme sıralaması bu nesne üzerinden ayarlanmaktadır.
  2. IEndpointRouteBuilder arayüzünü uyguladığı için MapGet, MapRazorPages vs. gibi metotlar aracılığıyla endpointler yapılandırılmaktadır.
    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    
    app.MapGet("/", () => "Hello World!");
    
    app.Run();
    
    
  3. IHost arayüzünü uyguladığından dolayı Run metodu eşliğinde uygulama başlatılmaktadır.

WebApplicationBuilder nesnesinin Build metodu tetiklendiğinde bir generic host instance’ı oluşturulur ve bu WebApplication türünde geri döndürülür.

WebApplication Nesnesi Başlatma ve Middleware Pipeline’ı Oluşturma

Web uygulamasını başlatmanın standart yolu WebApplication nesnesi üzerinden Run() ya da RunAsync() metotlarından birini çağırmaktır. Bu metotlar nihai olarak IHost.StartAsync metodunu tetikler ve böylece aşağıdaki görseldeki karmaşık metot etkileşimlerinin başlamasına vesile olurlar.

Yukarıdaki şemada görüldüğü üzere Host’un ayağa kaldırılması sırasının bir parçası olarak IHostedService çalıştırılmaktadır. Bu middleware’in oluşturulduğu ve Kestrel sunucusunun dinlenmeye başlandığı zamandır.

Aynı şekilde görseldeki GenericWebHostService ise middleware pipeline’ının oluşturulduğu ve uygulamanın çalıştırılmak için Kestrel’e gönderildiği yerdir.

Bu süreç açısından, WebApplication‘ı generic host ile karşılaştırırsak eğer herhangi bir fark bulunmamaktadır.

WebApplication Middleware Pipeline

WebApplication generic host’a kıyasla çeşitli middleware’ler barındırmaktadır. WebApplicationBuilder ise varsayılan olarak Kestrel sunucusunu yapılandırır, HostFiltering Middleware‘ini ekler ve IIS entegrasyonunu etkinleştirir. Bunlara ek olarak WebApplicationBuilder nesnesi ekstradan middleware yapılanmasını kurar.

Şimdi bir Asp.NET Core uygulamasında middleware yapılanmasının nasıl kurulduğunu adım adım inceleyerek devam edelim.

  • UseRouting Middleware
    Burada UseRouting(RoutingMiddleware) middleware’ini incelememizin sebebi, bazı middleware’lerin UseRouting‘den önce çağrılması gerektiğidir. Haliyle RoutingMiddleware’inden önce çağrılması gereken bir middleware varsa ne yapılması gerekmektedir? gelin inceleyelim…

    Bunun için yapılması gereken tek şey UseRouting middleware’inin açıkça çağrılıp, devreye sokulmasıdır.

    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    app.MapGet("/", () => "Laylaylom galiba sana göre sevmeler...");
    app.Run();
    

    Böylece ilgili middleware’ler aşağıdaki gibi şekillenecektir.

    • HostFilteringMiddleware
    • DeveloperExceptionPageMiddleware
    • Aşağıdakileri içeren WebApplication nesnesi;
      • HttpsRedirectionMiddleware
      • StaticFilesMiddleware
      • RoutingMiddleware
    • EndpointMiddleware

  • UseRouting middleware’i yazıldığında ana/main middleware pipeline’ı ile WebApplication nesnesinin ApplicationBuilder pipeline’ı arasında genel düzenin korunması için WebApplicationBuilder bir işlevsellik göstermektedir. Bu işlevsellik, genel düzeni korumak üzere generic host’a dönmek gerektiğinde ortaya çıkacaktır.

  • UseEndpoint Pipeline
    EndpointMiddleware, MapGet vs. gibi metotlar eşliğinde ya da WebApplicationBuilder nesnesi ile otomatik ekleniyor olasa da UseEndpoints metodu eşliğinde de manuel bir şekilde çağrılarak, eklenebilmektedir.
    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    app.MapGet("/", () => "Laylaylom galiba sana göre sevmeler...");
    app.UseEndpoints(endpoint => endpoint.MapGet("/x", () => "doldur be meyhaneci boş kalmasın kadehim"));
    app.Run();
    

    Haliyle yukarıdaki inşa ile aşağıdaki middleware yapılanması elde edilecektir.

    • HostFilteringMiddleware
    • DeveloperExceptionPageMiddleware
    • Aşağıdakileri içeren WebApplication nesnesi;
      • HttpsRedirectionMiddleware
      • StaticFilesMiddleware
      • RoutingMiddleware
      • EndpointMiddleware
    • EndpointMiddleware
  • Yukarıdaki davranış ile endpoint’leri doğrudan hem WebApplication‘da hem de EndpointMiddleware‘in çağrısında kaydetmiş oluyoruz.

    Burada dikkat edilmesi gereken önemli bir nokta vardır, o da; UseEndpoints middleware’i manuel kullanılıyorsa kesinlikle UseRouting middleware’i de manuel çağrılmalıdır. Aksi taktirde hata alınacaktır.

    Nihai olarak;
    WebApplication nesnesi üzerinden yapılan çalışmalarda middleware pipeline’ının nasıl ve ne şekilde oluşturulduğunu görmüş ve incelemiş olduk. Böylece artık .NET 6 ile geliştirilen web uygulamalarında, konfigürasyon yapılanmasında neyin ne olduğuna ve ne şekilde davranış sergilediğine tam olarak vakıf bir şekilde geliştirmeler yapabilir ve nimetlerinden daha bilinçli faydalanabiliriz.

    İlgilenenlerin faydalanması dileğiyle…
    Sonraki yazılarımda görüşmek üzere…
    İyi çalışmalar…

    Exit mobile version