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

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>();

并保持控制器的构造函数不变。

【讨论】:

以上是关于如何解决“尝试激活''时无法解析类型''的服务”的主要内容,如果未能解决你的问题,请参考以下文章

如何解决mysql数据库8小时无连接自动关闭

如何解决 CameraX 应用程序无响应的问题?

如何解决 MS SQL 中不受支持的无符号整数字段类型?

Java实现文件流下载文件,浏览器无反应,后台无错误!如何解决?

linux(centos)无中文输入,如何解决

linux服务器如何切换用户,解决无权限上传文件问题