如何解决“尝试激活 '' 时无法解析类型 '' 的服务”

Gol*_*ide 5 c# dependency-injection asp.net-core asp.net-core-webapi

当我尝试从 Postman 向 .net core 3.1 WebAPI 发出请求时,出现错误

System.InvalidOperationException:尝试激活“PaymentsAPI.Controllers.PaymentController”时无法解析类型“PaymentsAPI.Repository.PaymentService”的服务

启动.cs

public void ConfigureServices(IServiceCollection services)
{      
    services.AddControllers();
  
    services.AddCors(c =>
    {
        c.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin());
    });
    services.AddDbContext<ApplicationDbContext>(o => o.UseSqlServer(Configuration.GetConnectionString("SqlSvrConn")));
    services.AddTransient<IAsyncPaymentsService<PaymentDetail>, PaymentService>();
}
Run Code Online (Sandbox Code Playgroud)

IAsyncPaymentsService.cs

public interface IAsyncPaymentsService<TEntity>
{        
    Task<IEnumerable<TEntity>> GetAllAsync();
}
Run Code Online (Sandbox Code Playgroud)

PaymentService.cs

public class PaymentService : IAsyncPaymentsService<PaymentDetail>
{
    private readonly ApplicationDbContext _dbContext;
    

    public async Task<IEnumerable<PaymentDetail>> GetAllAsync()
    {
        return await _dbContext.PaymentDetails.ToListAsync();
    }
}
Run Code Online (Sandbox Code Playgroud)

PaymentController.cs

[ApiController]
[Route("[controller]")]
public class PaymentController : ControllerBase
{
    private readonly ApplicationDbContext _context;
    private readonly PaymentService _service;
    public PaymentController(ApplicationDbContext context, PaymentService service)
    {
        _context = context;
        _service = service;
    }

    [HttpGet]
    public async Task<ActionResult<IEnumerable<PaymentDetail>>> GetAsync()
    {
        var items = (await _service.GetAllAsync());
        return Ok(items);
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试重新排列容器中的服务顺序,但错误仍然存​​在。我缺少什么?

Nko*_*osi 7

快速修复方法是将控制器构造函数更改为依赖于抽象而不是实现,因为抽象是在容器中注册的。

//...

private readonly ApplicationDbContext _context;
private readonly IAsyncPaymentsService<PaymentDetail> _service;

public PaymentController(ApplicationDbContext context, IAsyncPaymentsService<PaymentDetail> service)
{
    _context = context;
    _service = service;
}

//...
Run Code Online (Sandbox Code Playgroud)

但是,如果需要,通用抽象可以派生为封闭类型

public interface IPaymentService :  IAsyncPaymentsService<PaymentDetail> {

}
Run Code Online (Sandbox Code Playgroud)

应用于实施

public class PaymentService : IPaymentService {
    //...omitted for brevity
}
Run Code Online (Sandbox Code Playgroud)

注册到容器中

services.AddTransient<IPaymentService, PaymentService>();
Run Code Online (Sandbox Code Playgroud)

并在控制器中重构

//...

private readonly ApplicationDbContext _context;
private readonly IPaymentService _service;

public PaymentController(ApplicationDbContext context, IPaymentService service)
{
    _context = context;
    _service = service;
}

//...
Run Code Online (Sandbox Code Playgroud)