You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 6 Clean Architecture Web API服务解析失败问题求助

问题描述

基于ASP.NET Core 6构建Clean Architecture风格的Web API,测试CRUD的Get方法时触发System.InvalidOperationException: Unable to resolve service错误。各层结构如下:

  • 持久化层:包含ISPRepository接口、SPRepository实现类及SPContext
  • 应用层:实现IGetSPService接口与GetSPService实现类
  • API层:SPController依赖IGetSPService

持久化层代码

ISPRepository接口

using Domain.Entities;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace Domain.Interfaces.IRepositories
{
    public interface ISPRepository
    {
        Task<List<SP>> GetByIdsAsync(int ids);

        Task<List<SP>> GetAllAsync();
    }
}

SPRepository实现类

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Domain.Entities;
using Domain.Interfaces.IRepositories;
using Persistence.DBContext;


 namespace Persistence.Repositories
{
    public  class SPRepository: ISPRepository
    {
        private readonly SPContext _context;
        
        // 根据ID获取SP
        public async Task<List<SP>> GetByIdsAsync(int ids)
        {
            return await this._context
                .SPs
                .Where(x => x.SPId==ids).ToListAsync();
        }
        // 获取所有SP
        public async Task<List<SP>> GetAllAsync()
        {
            return await this._context
                .SPs
                .ToListAsync();
        }
    }
}

应用层代码

IGetSPService接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SP.Domain.Entities;
namespace SP.Application.SP.Queries.Iservices
{
    public interface IGetSPService
    {
        Task<List<SP>> GetSPByIdAsync(int SPId);
        Task<List<SP>> GetAllAsync();
    }
}

GetSPService实现类

using SP.Domain.Interfaces.IRepositories;
using SP.Domain.Entities;
using SP.Application.SP.Queries.Iservices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SP.Application.SP.Queries.Services
{
    public  class GetSPService: IGetSPService
    {
        private readonly ISPRepository  _SPRepository;

        public GetSPService(ISPRepository SPRepository)
        {
            _SPRepository = SPRepository;
        }
        
        public async Task<List<SP>> GetSPByIdAsync(int SPId)
        {
            return await _SPRepository.GetByIdsAsync(SPId);
        }
        public async Task<List<SP>> GetAllAsync()
        {
            return await _SPRepository.GetAllAsync();
        }
       
    }
}

API层代码

SPController

using Microsoft.AspNetCore.Mvc;
using SP.Application.SP.Queries.Iservices;
using SP.Domain.Entities;
using System.Xml;

namespace SP.Api.Server.Controllers
{
    [ApiController]
    [Route("api/[controller]")]

    public class SPController : ControllerBase
    {
        private readonly IGetSPService _service;
        public SPController(IGetSPService service)
        {
            _service = service;
        }
        [HttpGet("{id}")]
        public async Task<ActionResult<List<SP>>> GetSPById(int  id)
        {
            var entity = await _service.GetSPByIdAsync(id);

            if (entity == null)
            {
                return NotFound();
            }

            return entity;
        }
    }
}

原Program.cs代码

using Microsoft.EntityFrameworkCore;
using SP.Persistence.DBContext;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddHttpContextAccessor();*/


var app = builder.Build();


// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
                
app.UseHttpsRedirection();
// 解决localhost无法访问问题
app.UsePathBase("/SP.Api.Server");


app.UseAuthorization();

app.MapControllers();

app.Run();

问题原因与解决方法

错误核心是ASP.NET Core依赖注入容器未注册所需的服务接口与实现类,同时SPContext也未完成注册。需在Program.cs中补充以下注册逻辑:

修改后的Program.cs代码

using Microsoft.EntityFrameworkCore;
using SP.Persistence.DBContext;
using Domain.Interfaces.IRepositories;
using Persistence.Repositories;
using SP.Application.SP.Queries.Iservices;
using SP.Application.SP.Queries.Services;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// 1. 注册SPContext,配置数据库连接(示例为SQL Server,可根据实际替换)
builder.Services.AddDbContext<SPContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

// 2. 注册仓储:绑定接口与实现类
builder.Services.AddScoped<ISPRepository, SPRepository>();

// 3. 注册应用服务:绑定接口与实现类
builder.Services.AddScoped<IGetSPService, GetSPService>();

builder.Services.AddHttpContextAccessor();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UsePathBase("/SP.Api.Server");

app.UseAuthorization();

app.MapControllers();

app.Run();

关键说明

  1. SPContext注册:需在appsettings.json中配置对应连接字符串DefaultConnection,示例:
    {
      "ConnectionStrings": {
        "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=SPDB;Trusted_Connection=True;MultipleActiveResultSets=true"
      }
    }
    
  2. 仓储与服务注册:使用AddScoped(每个请求生命周期创建一个实例)完成接口与实现类的绑定,符合Clean Architecture的依赖倒置原则,容器会在需要时自动解析对应实现类。

内容的提问来源于stack exchange,提问作者Mira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 08:02:51