如何解决“尝试激活''时无法解析类型''的服务”
Posted
技术标签:
【中文标题】如何解决“尝试激活\'\'时无法解析类型\'\'的服务”【英文标题】:How do I resolve "Unable to resolve service for type '' while attempting to activate ''"如何解决“尝试激活''时无法解析类型''的服务” 【发布时间】:2021-09-26 00:22:41 【问题描述】:当我尝试从 Postman 请求 .net core 3.1 WebAPI 时出现错误
System.InvalidOperationException:尝试激活“PaymentsAPI.Controllers.PaymentController”时无法解析“PaymentsAPI.Repository.PaymentService”类型的服务 '
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);
我已尝试重新排列容器中的服务顺序,但错误仍然存在。我错过了什么?
【问题讨论】:
【参考方案1】:快速解决方法是将控制器构造函数更改为依赖于抽象而不是实现,因为抽象是在容器中注册的内容。
//...
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;
//...
【讨论】:
【参考方案2】:要使这项工作正常进行,您唯一需要更改的就是将接口接受到您的控制器中,而不是具体服务。
public PaymentController(ApplicationDbContext context, IAsyncPaymentsService<PaymentDetail> service)
...
出于各种原因(例如测试),建议使用具体类型。如果您确实需要具体类型,则必须改为将注册更改为
services.AddTransient<PaymentService>();
并保持控制器的构造函数不变。
【讨论】:
以上是关于如何解决“尝试激活''时无法解析类型''的服务”的主要内容,如果未能解决你的问题,请参考以下文章