我该如何解决 "Unable to resolve service for type '' while attempting to activate ''"
How do I resolve "Unable to resolve service for type '' while attempting to activate ''"
当我尝试从 Postman 请求 .net core 3.1 WebAPI 时出现错误
System.InvalidOperationException: Unable to resolve service for type 'PaymentsAPI.Repository.PaymentService' while attempting to activate 'PaymentsAPI.Controllers.PaymentController'
'
Startup.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>();
}
IAsyncPaymentsService.cs
public interface IAsyncPaymentsService<TEntity>
{
Task<IEnumerable<TEntity>> GetAllAsync();
}
PaymentService.cs
public class PaymentService : IAsyncPaymentsService<PaymentDetail>
{
private readonly ApplicationDbContext _dbContext;
public async Task<IEnumerable<PaymentDetail>> GetAllAsync()
{
return await _dbContext.PaymentDetails.ToListAsync();
}
}
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);
}
}
我已经尝试重新排列容器中的服务顺序,但错误仍然存在。我错过了什么?
快速解决方法是将控制器构造函数更改为依赖于抽象而不是实现,因为抽象是在容器中注册的内容。
//...
private readonly ApplicationDbContext _context;
private readonly IAsyncPaymentsService<PaymentDetail> _service;
public PaymentController(ApplicationDbContext context, IAsyncPaymentsService<PaymentDetail> service)
{
_context = context;
_service = service;
}
//...
但是,如果需要,泛型抽象可以派生为封闭类型
public interface IPaymentService : IAsyncPaymentsService<PaymentDetail> {
}
应用于实施
public class PaymentService : IPaymentService {
//...omitted for brevity
}
注册容器
services.AddTransient<IPaymentService, PaymentService>();
并在控制器中重构
//...
private readonly ApplicationDbContext _context;
private readonly IPaymentService _service;
public PaymentController(ApplicationDbContext context, IPaymentService service)
{
_context = context;
_service = service;
}
//...
要使此工作正常进行,您唯一需要更改的是在控制器中接受接口而不是具体服务。
public PaymentController(ApplicationDbContext context, IAsyncPaymentsService<PaymentDetail> service)
{...}
出于测试等各种原因,建议采用具体类型。如果您确实需要具体类型,则必须改为将注册更改为
services.AddTransient<PaymentService>();
并保持控制器的构造函数不变。
当我尝试从 Postman 请求 .net core 3.1 WebAPI 时出现错误
System.InvalidOperationException: Unable to resolve service for type 'PaymentsAPI.Repository.PaymentService' while attempting to activate 'PaymentsAPI.Controllers.PaymentController' '
Startup.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>();
}
IAsyncPaymentsService.cs
public interface IAsyncPaymentsService<TEntity>
{
Task<IEnumerable<TEntity>> GetAllAsync();
}
PaymentService.cs
public class PaymentService : IAsyncPaymentsService<PaymentDetail>
{
private readonly ApplicationDbContext _dbContext;
public async Task<IEnumerable<PaymentDetail>> GetAllAsync()
{
return await _dbContext.PaymentDetails.ToListAsync();
}
}
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);
}
}
我已经尝试重新排列容器中的服务顺序,但错误仍然存在。我错过了什么?
快速解决方法是将控制器构造函数更改为依赖于抽象而不是实现,因为抽象是在容器中注册的内容。
//...
private readonly ApplicationDbContext _context;
private readonly IAsyncPaymentsService<PaymentDetail> _service;
public PaymentController(ApplicationDbContext context, IAsyncPaymentsService<PaymentDetail> service)
{
_context = context;
_service = service;
}
//...
但是,如果需要,泛型抽象可以派生为封闭类型
public interface IPaymentService : IAsyncPaymentsService<PaymentDetail> {
}
应用于实施
public class PaymentService : IPaymentService {
//...omitted for brevity
}
注册容器
services.AddTransient<IPaymentService, PaymentService>();
并在控制器中重构
//...
private readonly ApplicationDbContext _context;
private readonly IPaymentService _service;
public PaymentController(ApplicationDbContext context, IPaymentService service)
{
_context = context;
_service = service;
}
//...
要使此工作正常进行,您唯一需要更改的是在控制器中接受接口而不是具体服务。
public PaymentController(ApplicationDbContext context, IAsyncPaymentsService<PaymentDetail> service)
{...}
出于测试等各种原因,建议采用具体类型。如果您确实需要具体类型,则必须改为将注册更改为
services.AddTransient<PaymentService>();
并保持控制器的构造函数不变。