c# - 将依赖注入(inject)应用于抽象类 c# 的不同实现

标签 c# api asp.net-core model-view-controller dependency-injection

当我可以在我的 Controller 中注入(inject)抽象类的 2 个不同实现时,我想在我的 .net 核心应用程序中构建一个 MVC 场景。这些实现调用它们的外部相关 API。也许架构是错误的,因此我向您征求建议,但请首先按照我的想法进行。 我创建了一个通用的抽象类。为什么要抽象?因为调用 API 的基本方式/属性对每个人来说都是相同的。就我而言,到目前为止我只有一个 HttpClient。

public abstract class ApiCaller
{
    protected static HttpClient client;
    protected static string ApiUrl;

    public ApiCaller(string apiUrl)
    {
        client = new HttpClient();
        ApiUrl = apiUrl;
    }

    public abstract string GetApiResultAsync();
}

之后,我将拥有两个不同的类 Api1ServiceApi2Service,它们扩展了 ApiCaller 并且将有自己不同的调用相关 API 的方式.

public class Api1Service : ApiCaller
{
    public Api1Service(string apiUrl) : base(apiUrl)
    {

    }

    public override string GetApiResultAsync()
    {
        ...
    }
}


public class Api2Service : ApiCaller
{
    public Api2Service(string apiUrl) : base(apiUrl)
    {

    }

    public override string GetApiResultAsync()
    {
        ...
    }
}

现在,我想在我的 Controller 中注入(inject)两个实例,因为我想使用这两个业务服务..但我不知道这是否可行。

[Route("api/[controller]")]
[ApiController]
public class MyController : ControllerBase
{
    private readonly ApiCaller _apiCaller;

    public BooksAndAlbumsController(ApiCaller apiCaller)
    {
        _apiCaller = apiCaller;
    }

    [HttpPost]
    public void Post([FromBody] string value)
    {
        _apiCaller.GetApiResultAsync() //but I want to use both my apiCallers
    }
}

因此,不知何故,在我的容器中我需要注册我的抽象类的两个实现。我怎样才能做到这一点?如果您发现我的架构中存在缺陷,请告诉我!

最佳答案

您可以注入(inject) IEnumerable<ApiCaller>然后同时使用它们。

在容器中注册两个 ApiCaller,然后注入(inject) IEnumerable<ApiCaller>在你的 Controller 中。

像这样:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<ApiCaller, Api1Service>();
    services.AddSingleton<ApiCaller, Api2Service>();
}

我的 Controller

[Route("api/[controller]")]
[ApiController]
public class MyController : ControllerBase
{
    private readonly IEnumerable<ApiCaller> _apiCallers;

    public MyController(IEnumerable<ApiCaller> apiCallers)
    {
        _apiCallers = apiCallers;
    }

    [HttpPost]
    public async Task Post([FromBody] string value)
    {
        // Loop through one by one or call them in parallel, up to you.
        foreach(var apiCaller in _apiCallers)
        {
            var result = await apiCaller.GetApiResultAsync();
        }
    }
}

另一种可能性是注册 Api1Service 和 Api2Service 然后像这样注入(inject)它们。不过,它不会像第一个解决方案那样动态/灵活。

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<Api1Service>();
    services.AddSingleton<Api2Service>();
}

我的 Controller

[Route("api/[controller]")]
[ApiController]
public class MyController : ControllerBase
{
    private readonly Api1Service _api1Service;
    private readonly Api2Service _api2Service;

    public MyController(Api1Service api1Service, Api2Service api2Service)
    {
        _api1Service = api1Service;
        _api2Service = api2Service;
    }

    [HttpPost]
    public async Task Post([FromBody] string value)
    {
        var result1 = await apiService1.GetApiResultAsync();
        var result2 = await apiService2.GetApiResultAsync();
    }
}

关于c# - 将依赖注入(inject)应用于抽象类 c# 的不同实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55983502/

相关文章:

ruby-on-rails - 博客平台推荐的Url格式

c# - 如何将多部分/表单数据发送到 ASP.NET Core Web API?

c# - 将左列添加到 MVC Net Core 元素模板 View 中,该 View 会随着用户向下滚动而消失

.net - 什么对 REST API 更好? WCF Web API(预览版 4)或 OpenRasta 或其他什么?

api - Paypal 捐款 - "Gift Aid"

c# - 使用 HTTP GET : ASP . NET CORE API 流式传输文件

c# - 如何在列表框 WP8 中绑定(bind)数据用户控件

c# - 在另一个程序集中找到 Razor Pages

c# - 我无法使用 Selenium 和 C# 在日期选择器上选择日期

c# - 如何告诉 Automapper 检查所有源属性是否都有目标属性