首页 > 解决方案 > 如果接口未实例化,则依赖注入问题

问题描述

我正在使用 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(?)

标签: c#entity-frameworkasp.net-coredependency-injectionasp.net-core-mvc

解决方案


如果您想解析 ZoneRepository ,那么您还需要将其注册为此类。

services.AddScoped<ZoneRepository, ZoneRepository>();

虽然我建议创建一个新接口,IZoneRepository继承自IBaseRepository<Zone>以保持它易于测试。


推荐阅读