Özel ASP.NET Core ara yazılımı yazma

Fiyaz Hasan, Rick Anderson ve Steve Smith tarafından

Ara yazılım, istekleri ve yanıtları işlemek için uygulama işlem hattıyla birleştirilmiş bir yazılımdır. ASP.NET Core, zengin bir yerleşik ara yazılım bileşenleri kümesi sağlar, ancak bazı senaryolarda özel bir ara yazılım yazmak isteyebilirsiniz.

Bu konu başlığında kural tabanlı ara yazılımların nasıl yazıldığı açıklanmaktadır. Güçlü yazma ve istek başına etkinleştirme kullanan bir yaklaşım için bkz . ASP.NET Core'da fabrika tabanlı ara yazılım etkinleştirme.

Ara yazılım sınıfı

Ara yazılım genellikle bir sınıfta kapsüllenmiş ve bir uzantı yöntemiyle kullanıma sunulur. Sorgu dizesinden geçerli isteğin kültürünü ayarlayan aşağıdaki satır içi ara yazılımı göz önünde bulundurun:

using System.Globalization;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.UseHttpsRedirection();

app.Use(async (context, next) =>
{
    var cultureQuery = context.Request.Query["culture"];
    if (!string.IsNullOrWhiteSpace(cultureQuery))
    {
        var culture = new CultureInfo(cultureQuery);

        CultureInfo.CurrentCulture = culture;
        CultureInfo.CurrentUICulture = culture;
    }

    // Call the next delegate/middleware in the pipeline.
    await next(context);
});

app.Run(async (context) =>
{
    await context.Response.WriteAsync(
        $"CurrentCulture.DisplayName: {CultureInfo.CurrentCulture.DisplayName}");
});

app.Run();

Yukarıdaki vurgulanan satır içi ara yazılım, çağrılarak Microsoft.AspNetCore.Builder.UseExtensions.Useara yazılım bileşeni oluşturmayı göstermek için kullanılır. Yukarıdaki Use uzantı yöntemi, uygulamanın istek işlem hattına satır içinde tanımlanmış bir ara yazılım temsilcisi ekler.

Uzantı için Use iki aşırı yükleme vardır:

  • Biri ve bir HttpContextFunc<Task>alır. parametresi olmadan öğesini Func<Task> çağırın.
  • Diğeri ve HttpContextRequestDelegatealır. RequestDelegate geçirerek öğesini çağırınHttpContext.

Diğer aşırı yükleme kullanılırken gerekli olan iki iç istek başına ayırmayı kaydettiğinden sonraki aşırı yüklemeyi kullanmayı tercih edin.

Kültürü geçirerek ara yazılımı test edin. Örneğin, isteğinde bulun.https://localhost:5001/?culture=es-es

ASP.NET Core'un yerleşik yerelleştirme desteği için bkz . ASP.NET Core'da genelleştirme ve yerelleştirme.

Aşağıdaki kod ara yazılım temsilcisini bir sınıfa taşır:

using System.Globalization;

namespace Middleware.Example;

public class RequestCultureMiddleware
{
    private readonly RequestDelegate _next;

    public RequestCultureMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var cultureQuery = context.Request.Query["culture"];
        if (!string.IsNullOrWhiteSpace(cultureQuery))
        {
            var culture = new CultureInfo(cultureQuery);

            CultureInfo.CurrentCulture = culture;
            CultureInfo.CurrentUICulture = culture;
        }

        // Call the next delegate/middleware in the pipeline.
        await _next(context);
    }
}

Ara yazılım sınıfı şunları içermelidir:

  • türünde RequestDelegatebir parametreye sahip bir ortak oluşturucu.
  • veya InvokeAsyncadlı Invoke bir genel yöntem. Bu yöntem:
    • bir Taskdöndürür.
    • türünde HttpContextilk parametreyi kabul edin.

Oluşturucu için ek parametreler ve Invoke/InvokeAsync bağımlılık ekleme (DI) ile doldurulur.

Genellikle, ara yazılımı aracılığıyla IApplicationBuilderkullanıma açmak için bir uzantı yöntemi oluşturulur:

using System.Globalization;

namespace Middleware.Example;

public class RequestCultureMiddleware
{
    private readonly RequestDelegate _next;

    public RequestCultureMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var cultureQuery = context.Request.Query["culture"];
        if (!string.IsNullOrWhiteSpace(cultureQuery))
        {
            var culture = new CultureInfo(cultureQuery);

            CultureInfo.CurrentCulture = culture;
            CultureInfo.CurrentUICulture = culture;
        }

        // Call the next delegate/middleware in the pipeline.
        await _next(context);
    }
}

public static class RequestCultureMiddlewareExtensions
{
    public static IApplicationBuilder UseRequestCulture(
        this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<RequestCultureMiddleware>();
    }
}

Aşağıdaki kod tarafından Program.csara yazılımı çağırır:

using Middleware.Example;
using System.Globalization;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.UseHttpsRedirection();

app.UseRequestCulture();

app.Run(async (context) =>
{
    await context.Response.WriteAsync(
        $"CurrentCulture.DisplayName: {CultureInfo.CurrentCulture.DisplayName}");
});

app.Run();

Ara yazılım bağımlılıkları

Ara yazılım, bağımlılıklarını oluşturucusunda ortaya çıkararak Açık Bağımlılıklar İlkesi'ni izlemelidir. Ara yazılım, uygulama ömrü başına bir kez oluşturulur.

Ara yazılım bileşenleri bağımlılık ekleme (DI) ile oluşturucu parametreleri aracılığıyla bağımlılıklarını çözebilir. UseMiddleware ayrıca ek parametreleri doğrudan kabul edebilir.

İstek başına ara yazılım bağımlılıkları

Ara yazılım, uygulama başlangıcında oluşturulur ve bu nedenle uygulama ömrü süresine sahiptir. Ara yazılım oluşturucuları tarafından kullanılan kapsamlı yaşam süresi hizmetleri, her istek sırasında bağımlılık eklenmiş diğer türlerle paylaşılamaz. Ara yazılım ve diğer türler arasında kapsamlı bir hizmet paylaşmak için bu hizmetleri yöntemin imzasına InvokeAsync ekleyin. yöntemi, InvokeAsync DI tarafından doldurulan ek parametreleri kabul edebilir:

namespace Middleware.Example;

public class MyCustomMiddleware
{
    private readonly RequestDelegate _next;

    public MyCustomMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    // IMessageWriter is injected into InvokeAsync
    public async Task InvokeAsync(HttpContext httpContext, IMessageWriter svc)
    {
        svc.Write(DateTime.Now.Ticks.ToString());
        await _next(httpContext);
    }
}

public static class MyCustomMiddlewareExtensions
{
    public static IApplicationBuilder UseMyCustomMiddleware(
        this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<MyCustomMiddleware>();
    }
}

Yaşam süresi ve kayıt seçenekleri, kapsamlı yaşam süresi hizmetlerine sahip tam bir ara yazılım örneği içerir.

Yukarıdaki ara yazılımı test etmek için aşağıdaki kod kullanılır:

using Middleware.Example;
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddScoped<IMessageWriter, LoggingMessageWriter>();

var app = builder.Build();

app.UseHttpsRedirection();

app.UseMyCustomMiddleware();

app.MapGet("/", () => "Hello World!");

app.Run();

Arabirim IMessageWriter ve uygulama:

namespace Middleware.Example;

public interface IMessageWriter
{
    void Write(string message);
}

public class LoggingMessageWriter : IMessageWriter
{

    private readonly ILogger<LoggingMessageWriter> _logger;

    public LoggingMessageWriter(ILogger<LoggingMessageWriter> logger) =>
        _logger = logger;

    public void Write(string message) =>
        _logger.LogInformation(message);
}

Ek kaynaklar

Rick Anderson ve Steve Smith

Ara yazılım, istekleri ve yanıtları işlemek için uygulama işlem hattıyla birleştirilmiş bir yazılımdır. ASP.NET Core, zengin bir yerleşik ara yazılım bileşenleri kümesi sağlar, ancak bazı senaryolarda özel bir ara yazılım yazmak isteyebilirsiniz.

Dekont

Bu konu başlığında kural tabanlı ara yazılımların nasıl yazıldığı açıklanmaktadır. Güçlü yazma ve istek başına etkinleştirme kullanan bir yaklaşım için bkz . ASP.NET Core'da fabrika tabanlı ara yazılım etkinleştirme.

Ara yazılım sınıfı

Ara yazılım genellikle bir sınıfta kapsüllenmiş ve bir uzantı yöntemiyle kullanıma sunulur. Sorgu dizesinden geçerli isteğin kültürünü ayarlayan aşağıdaki ara yazılımı göz önünde bulundurun:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            var cultureQuery = context.Request.Query["culture"];
            if (!string.IsNullOrWhiteSpace(cultureQuery))
            {
                var culture = new CultureInfo(cultureQuery);

                CultureInfo.CurrentCulture = culture;
                CultureInfo.CurrentUICulture = culture;
            }

            // Call the next delegate/middleware in the pipeline
            await next();
        });

        app.Run(async (context) =>
        {
            await context.Response.WriteAsync(
                $"Hello {CultureInfo.CurrentCulture.DisplayName}");
        });

    }
}

Yukarıdaki örnek kod, ara yazılım bileşeni oluşturmayı göstermek için kullanılır. ASP.NET Core'un yerleşik yerelleştirme desteği için bkz . ASP.NET Core'da genelleştirme ve yerelleştirme.

Kültürü geçirerek ara yazılımı test edin. Örneğin, isteğinde bulun.https://localhost:5001/?culture=no

Aşağıdaki kod ara yazılım temsilcisini bir sınıfa taşır:

using Microsoft.AspNetCore.Http;
using System.Globalization;
using System.Threading.Tasks;

namespace Culture
{
    public class RequestCultureMiddleware
    {
        private readonly RequestDelegate _next;

        public RequestCultureMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            var cultureQuery = context.Request.Query["culture"];
            if (!string.IsNullOrWhiteSpace(cultureQuery))
            {
                var culture = new CultureInfo(cultureQuery);

                CultureInfo.CurrentCulture = culture;
                CultureInfo.CurrentUICulture = culture;

            }

            // Call the next delegate/middleware in the pipeline
            await _next(context);
        }
    }
}

Ara yazılım sınıfı şunları içermelidir:

  • türünde RequestDelegatebir parametreye sahip bir ortak oluşturucu.
  • veya InvokeAsyncadlı Invoke bir genel yöntem. Bu yöntem:
    • bir Taskdöndürür.
    • türünde HttpContextilk parametreyi kabul edin.

Oluşturucu için ek parametreler ve Invoke/InvokeAsync bağımlılık ekleme (DI) ile doldurulur.

Ara yazılım bağımlılıkları

Ara yazılım, bağımlılıklarını oluşturucusunda ortaya çıkararak Açık Bağımlılıklar İlkesi'ni izlemelidir. Ara yazılım, uygulama ömrü başına bir kez oluşturulur. bir istek içinde ara yazılımla hizmet paylaşmanız gerekiyorsa, İstek başına ara yazılım bağımlılıkları bölümüne bakın.

Ara yazılım bileşenleri bağımlılık ekleme (DI) ile oluşturucu parametreleri aracılığıyla bağımlılıklarını çözebilir. UseMiddleware ayrıca ek parametreleri doğrudan kabul edebilir.

İstek başına ara yazılım bağımlılıkları

Ara yazılım istek başına değil uygulama başlangıcında oluşturulurken, ara yazılım oluşturucuları tarafından kullanılan kapsamlı yaşam süresi hizmetleri, her istek sırasında bağımlılık eklenmiş diğer türlerle paylaşılmaz. Ara yazılımınızla diğer türler arasında kapsamlı bir hizmet paylaşmanız gerekiyorsa, bu hizmetleri yöntemin imzasına InvokeAsync ekleyin. yöntemi, InvokeAsync DI tarafından doldurulan ek parametreleri kabul edebilir:

public class CustomMiddleware
{
    private readonly RequestDelegate _next;

    public CustomMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    // IMyScopedService is injected into InvokeAsync
    public async Task InvokeAsync(HttpContext httpContext, IMyScopedService svc)
    {
        svc.MyProperty = 1000;
        await _next(httpContext);
    }
}

Yaşam süresi ve kayıt seçenekleri, kapsamlı yaşam süresi hizmetlerine sahip tam bir ara yazılım örneği içerir.

Ara yazılım uzantısı yöntemi

Aşağıdaki uzantı yöntemi ara yazılımı aracılığıyla IApplicationBuilderkullanıma sunar:

using Microsoft.AspNetCore.Builder;

namespace Culture
{
    public static class RequestCultureMiddlewareExtensions
    {
        public static IApplicationBuilder UseRequestCulture(
            this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<RequestCultureMiddleware>();
        }
    }
}

Aşağıdaki kod tarafından Startup.Configureara yazılımı çağırır:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseRequestCulture();

        app.Run(async (context) =>
        {
            await context.Response.WriteAsync(
                $"Hello {CultureInfo.CurrentCulture.DisplayName}");
        });
    }
}

Ek kaynaklar