Tar*_*rta 2 c# api model-view-controller dependency-injection asp.net-core
当我可以在我的控制器中注入抽象类的 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();
}
Run Code Online (Sandbox Code Playgroud)
之后,我将拥有两个不同的类Api1Service和Api2Service,它们扩展了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()
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
现在,在我的控制器中,我想注入两个实例,因为我想使用这两个业务服务..但我不知道这是否可能。
[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
}
}
Run Code Online (Sandbox Code Playgroud)
所以,不知何故,在我的容器中,我需要注册我的抽象类的两个实现。我怎样才能做到这一点?如果您发现我的架构中存在缺陷,请告诉我!
您可以注入一个IEnumerable<ApiCaller>然后同时使用它们。
在容器中注册两个 ApiCallers,然后将 注入到IEnumerable<ApiCaller>您的控制器中。
像这样的东西:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ApiCaller, Api1Service>();
services.AddSingleton<ApiCaller, Api2Service>();
}
Run Code Online (Sandbox Code Playgroud)
我的控制器
[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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
另一种可能是注册 Api1Service 和 Api2Service,然后像这样注入它们。不过,它不会像第一个解决方案那样动态/灵活。
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<Api1Service>();
services.AddSingleton<Api2Service>();
}
Run Code Online (Sandbox Code Playgroud)
我的控制器
[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();
}
}
Run Code Online (Sandbox Code Playgroud)