Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Khác biệt giữa IApplicationBuilder.Use() và IApplicationBuilder.Run() trong C# ASP.NET Core

Chúng ta có thể cấu hình middleware trong phương thức Configure của lớp Startup sử dụng instance IApplicationBuilder.

Run() là extension method trên instance IApplicationBuilder thêm một terminal middleware vào request pipeline của ứng dụng.

Phương thức Run là extension method trên IApplicationBuilder và chấp nhận tham số kiểu RequestDelegate.

Signature của Run method

public static void Run(this IApplicationBuilder app, RequestDelegate handler)

Signature của RequestDelegate

public delegate Task RequestDelegate(HttpContext context);

Ví dụ Run()

public class Startup { 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { 
        app.Run(async (context) => { 
            await context.Response.WriteAsync("Hello World!"); 
        }); 
    } 
}

Hàm MyMiddleware ở trên không phải async và sẽ block thread cho đến khi hoàn thành. Nên làm nó async bằng async/await để cải thiện performance và scalability.

public class Startup { 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env) { 
        app.Run(MyMiddleware); 
    } 
    
    private async Task MyMiddleware(HttpContext context) { 
        await context.Response.WriteAsync("Hello World!"); 
    } 
}

Cấu hình Multiple Middleware dùng Run()

Sau đây sẽ luôn thực thi Run method đầu tiên và không bao giờ đến Run method thứ hai:

public void Configure(IApplicationBuilder app, IHostingEnvironment env) { 
    app.Run(async (context) => { 
        await context.Response.WriteAsync("1st Middleware"); 
    }); 
    // Đoạn dưới sẽ không bao giờ thực thi
    app.Run(async (context) => { 
        await context.Response.WriteAsync("2nd Middleware"); 
    }); 
}

USE()

Để cấu hình multiple middleware, dùng extension method Use(). Nó tương tự Run() trừ việc nó bao gồm tham số next để invoke middleware tiếp theo trong chuỗi.

public void Configure(IApplicationBuilder app, IHostingEnvironment env) { 
    app.Use(async (context, next) => { 
        await context.Response.WriteAsync("1st Middleware!"); 
        await next(); // Gọi middleware tiếp theo
    }); 
    app.Run(async (context) => { 
        await context.Response.WriteAsync("2nd Middleware"); 
    }); 
}

So sánh chi tiết

Đặc điểm Use() Run()
Tham số HttpContext, Func<Task> next HttpContext
Có thể gọi middleware tiếp theo Có (qua next()) Không (terminal)
Số lượng trong pipeline Nhiều Chỉ 1 (cuối cùng)
Use case Middleware trung gian (logging, auth, v.v.) Terminal middleware (trả về response cuối)

Middleware Pipeline Pattern

public void Configure(IApplicationBuilder app) {
    // Middleware 1: Logging
    app.Use(async (context, next) => {
        var start = DateTime.UtcNow;
        await next();
        var duration = DateTime.UtcNow - start;
        Console.WriteLine($"Request took {duration.TotalMs}ms");
    });
    
    // Middleware 2: Authentication
    app.UseAuthentication();
    
    // Middleware 3: Authorization
    app.UseAuthorization();
    
    // Terminal middleware: MVC/Razor Pages
    app.UseEndpoints(endpoints => {
        endpoints.MapControllers();
    });
}