Asp-NET Core 一個接口的多個實現如何基於當前 HTTP 請求註冊

前言

假設我們有三個 Service 類實現了同一接口,示例代碼如下:

public interface IService { }
public class ServiceA : IService { }
public class ServiceB : IService { } 
public class ServiceC : IService { }

我們希望在運行時使用依賴注入指定其具體實現類。

在本文中,我們將演示如何使用 HTTP 請求設置依賴項設置來實現。

Demo

首先,在 Startup.cs 中做多個實現類註冊:

services.AddHttpContextAccessor();

services.AddTransient<ServiceA>();
services.AddTransient<ServiceB>();
services.AddTransient<ServiceC>();

services.AddTransient<IService>(serviceProvider =>
{
    var context = serviceProvider.GetRequiredService<IHttpContextAccessor>();

    var containsKey = context.HttpContext?.Request?.Query?.ContainsKey("key");
    var key = containsKey.HasValue  && containsKey.Value ? context.HttpContext?.Request?.Query?["key"].First()"A";

    switch (key)
    {
        case "A":
            return serviceProvider.GetService<ServiceA>();
        case "B":
            return serviceProvider.GetService<ServiceB>();
        case "C":
            return serviceProvider.GetService<ServiceC>();
        default:
            throw new KeyNotFoundException();
    }
});

在這裏,我們通過獲取 HTTP 上下文並檢查是否定義了 key 查詢字符串參數。

現在,可以向普通方式一樣使用 IService,示例代碼如下:

[ApiController]
[Route("[controller]")]
public class DemoController : ControllerBase
{
    private readonly IService _service;

    public DemoController(IService service)
    {
        this._service = service;
    }

    [HttpGet]
    public async Task<string> Get()
    {
        return _service.GetType().Name;
    }
}

通過從查詢字符串中讀取值,可以控制具體的 IService 實現類:

結論

=====

當然,我們不僅可以將此策略用於查詢字符串中的值,還可以對標頭、Body 等 HTTP 請求包含的任何值使用此策略。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/biyKVd2411gdkTBo5aYuKw