c# - 如果接口未实例化,则依赖注入问题
问题描述
我正在使用 EntityFramework 开发一个 API。一切进展顺利。
namespace ControlTec.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ZoneController : Controller, IBaseController<Zone>, IBaseRules<Zone>
{
private readonly IBaseRepository<Zone> _zoneRepository;
public const int ID_INSERT = 0;
public ZoneController(IBaseRepository<Zone> zoneRepository)
{
_zoneRepository = zoneRepository;
}
[HttpGet]
public async Task<ActionResult<List<Zone>>> GetAll()
{
return await _zoneRepository.GetAll();
}
}
}
namespace ControlTec.Models
{
public interface IBaseRepository<T> where T : new()
{
Task<T> Add(T objModel);
Task<T> Update(T objModel);
Task<T> Remove(int id);
Task<T> GetById(int id);
Task<List<T>> GetAll();
}
}
namespace ControlTec.Models
{
public class ZoneRepository : IBaseRepository<Zone>
{
private readonly DataContext _context;
public ZoneRepository(DataContext context)
{
_context = context;
}
public async Task<Zone> Add(Zone objModel)
{
_context.Zone.Add(objModel);
await _context.SaveChangesAsync();
return await GetById(objModel.Id);
}
public async Task<Zone> GetById(int id)
{
var zone = await _context.Zone.FirstOrDefaultAsync(t => t.Id == id);
return zone;
}
public async Task<Zone> GetByName(string name)
{
var zone = await _context.Zone.FirstOrDefaultAsync(t => t.Name == name);
return zone;
}
public async Task<List<Zone>> GetAll()
{
return await _context.Zone.ToListAsync();
}
public async Task<Zone> Remove(int id)
{
var zone = await GetById(id);
_context.Remove(zone);
await _context.SaveChangesAsync();
return zone;
}
public async Task<Zone> Update(Zone objModel)
{
var zone = await GetById(objModel.Id);
zone.Name = objModel.Name;
await _context.SaveChangesAsync();
return objModel;
}
}
}
配置服务
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureProblemDetailsModelState();
// services.AddGlobalExceptionHandlerMiddleware();
services.AddControllers();
//------------------------------------------------------------------------------------------//
var connection = Configuration["ConexaoSqlite:SqliteConnectionString"];
services.AddDbContext<DataContext>(options => {
options.UseSqlite(connection);
});
services.AddScoped<IBaseRepository<Zone>, ZoneRepository>();
}
当我需要在 ZoneRepository 中创建一个新方法并且不想在接口中实现它时,问题就出现了。
这样,我就不能再实例化 IBaseRepository。
代码是:
namespace ControlTec.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ZoneController : Controller, IBaseController<Zone>, IBaseRules<Zone>
{
private readonly ZoneRepository _zoneRepository; //here
public const int ID_INSERT = 0;
public ZoneController(ZoneRepository zoneRepository) //here
{
_zoneRepository = zoneRepository;
}
[HttpGet]
public async Task<ActionResult<List<Zone>>> GetAll()
{
return await _zoneRepository.GetAll();
}
}
更改后,您将在下面收到异常。
System.InvalidOperationException: 尝试激活“ControlTec.Controllers.ZoneController”时无法解析“ControlTec.Models.ZoneRepository”类型的服务。\r\n 在对象 Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type , 类型 requiredBy, bool isDefaultParameterRequired)\r\n
在对象 lambda_method(Closure, IServiceProvider, object[])\r\n 在 Func Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.CreateActivator(ControllerActionDescriptor 描述符)+(ControllerContext controllerContext) => { }\r\n 在 Func Microsoft。 AspNetCore.Mvc.Controllers.ControllerFactoryProvider.CreateControllerFactory(ControllerActionDescriptor 描述符)+CreateController(ControllerContext controllerContext)\r\n at Task Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)\r\n 在任务 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()\r\n 在异步任务 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker。InvokeFilterPipelineAsync()+Awaited(?)\r\n 在异步任务 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeAsync()+Logged(?)\r\n 在异步任务 Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke( HttpContext httpContext)+AwaitRequestTask(?)\r\n 在异步任务 Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)+Awaited(?)
解决方案
如果您想解析 ZoneRepository ,那么您还需要将其注册为此类。
services.AddScoped<ZoneRepository, ZoneRepository>();
虽然我建议创建一个新接口,IZoneRepository
继承自IBaseRepository<Zone>
以保持它易于测试。
推荐阅读
- visual-studio - 控制台的本地 Nuget 包创建
- arrays - 检查值是否不在数组中最后一项的数组中
- python - 具有单独属性的 Tkinter 图像
- php - 如果我使用 CRON,脚本会在一段时间后停止运行,但如果我在浏览器中运行则不会
- vba - Excel公式转换成VBA,
- arrays - Excel VBA 将新行插入数组
- python - TypeError:列表索引必须是整数或切片,而不是使用python将json插入postgresql时的str
- java - 如何在 Java 中输入超过 4095 个字符的行?
- java - 这种建设的目的是什么?
- reactjs - 为团队使用设计框架