System.InvalidOperationException: 无法解析服务类型
System.InvalidOperationException: Unable to resolve service for type
我正在使用 ASP.NET 核心开发 Web API。当我使用 post 请求执行我的 API 时,在 UnitController 的 Post 方法中的断点之前抛出异常。
异常
Request starting HTTP/1.1 POST http://localhost:5000/api/unit
application/json 31 fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HKVTL9A1LTD4": An unhandled exception was thrown by the application. System.InvalidOperationException: Unable to resolve service for type 'Project.DataAccess.Repository.UnitRepository' while attempting to activate 'Project.Service.UnitService'.
上下文
namespace Project.DataAccess.Library.Interface {
public interface IBaseRepository<M> where M : class, IEntity
{
IEnumerable<M> SelectAll();
M SelectByID(int id);
void Insert(M obj);
void Update(M obj);
void Delete(int id);
void Save();
}
}
namespace Project.DataAccess.Library {
public abstract class BaseRepository<M> : IBaseRepository<M> where M : class, IEntity
{
protected ProjectContext Db { get; }
private DbSet<M> table = null;
protected DbSet<M> Table
{
get
{
return this.table;
}
}
public BaseRepository(ProjectContext dbContext)
{
Db = dbContext;
this.table = Db.Set<M>();
}
public void Delete(int id)
{
M existing = this.SelectByID(id);
if (existing != null)
this.table.Remove(existing);
}
// others methods
}
}
namespace Project.DataAccess.Repository
{
public class UnitRepository : BaseRepository<Unit>, IUnitRepository
{
public UnitRepository(Projectcontext) : base(context) { }
}
}
namespace Project.Service
{
public class UnitService : BaseService<Unit>, IUnitService
{
public UnitService(UnitRepository unitRepository) : base(unitRepository) { }
}
}
namespace AssoManager.Service.Library
{
public abstract class BaseService<M> : IBaseService<M> where M : class, IEntity
{
private IBaseRepository<M> _repository;
public BaseService(IBaseRepository<M> repository)
{
_repository = repository;
}
public IEnumerable<M> GetAll()
{
return this._repository.SelectAll();
}
}
}
namespace Project
{
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
this.DataAccessMySqlConfiguration(services);
this.ConfigureRepository(services);
this.ConfigureServicesUnit(services);
this.ConfigureServicesUser(services);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseMvc();
}
#region Database configuration
public void DataAccessMySqlConfiguration(IServiceCollection services)
{
services.AddDbContext<ProjectContext>(options => options.UseMySQL(Configuration.GetConnectionString("MsSQLConnection")));
}
#endregion
#region DataAccess configuration
public void ConfigureRepository(IServiceCollection services)
{
services.AddScoped<IUnitRepository, UnitRepository>();
services.AddScoped<IUserRepository, UserRepository>();
}
#endregion
#region Services configuration
/// <summary>
/// Is used to add unit services to the container
/// </summary>
public void ConfigureServicesUnit(IServiceCollection services)
{
services.AddTransient<IUnitService, UnitService>();
services.AddTransient<IMeetingService, MeetingService>();
}
/// <summary>
/// Is used to add user services to the container
/// </summary>
public void ConfigureServicesUser(IServiceCollection services)
{
services.AddTransient<IUserService, UserService>();
}
#endregion Services configuration
}
}
namespace Project.Controllers
{
[Route("api/[controller]")]
public class UnitController : Controller
{
private IUnitService UnitService;
public UnitController(IUnitService unitService)
{
UnitService = unitService;
}
// GET api/units
[HttpGet]
public IEnumerable<Unit> Get()
{
return UnitService.GetAll();
}
// GET api/unit/5
[HttpGet("{id}")]
public IActionResult Get(int id)
{
Unit unit;
//->Check
if (id < 1)
return BadRequest();
//->Processing
unit = UnitService.GetByID(id);
if (unit == null)
return NotFound();
return new ObjectResult(unit);
}
// POST api/unit
[HttpPost]
public IActionResult Post([FromBody]Unit unit)
{
//->Check
if (unit == null)
return BadRequest();
//->Processing
UnitService.Create(unit);
return CreatedAtRoute("Get", new { id = unit.Id }, unit);
}
// PUT api/unit/5
[HttpPut("{id}")]
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/unit/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}
版本
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.0",
"type": "platform"
},
"Microsoft.AspNetCore.Mvc": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
"Microsoft.EntityFrameworkCore": "1.0.0",
"MySql.Data.Core": "7.0.4-IR-191",
"MySql.Data.EntityFrameworkCore": "7.0.4-IR-191",
"IdentityServer4": "1.0.0-rc2",
"AssoManager.Domain": "1.0.0-*",
"AssoManager.Service": "1.0.0-*",
"AssoManager.DataAccess": "1.0.0-*"
},
问题
我认为问题可能出在 BaseRepository 和 IBaseRepository 之间的继承上。但我不明白我的错误在哪里。
我该如何纠正这个错误?
感谢您的帮助:),
您正在将 UnitRepository 注册为 IUnitRepository,但请求您的 IoC 解析 UnitRepository。它没有注册,所以它失败了。
尝试让 UnitService 使用 IUnitRepository 而不是 UnitRepository,这应该可以解决问题(请原谅双关语)。
我发现 Callum Bradbury 的答案非常有用(谢谢你,Callum),但我认为更一般的答案可能适用于不同的情况。所以:
当你在给定的 class 中使用 DI(依赖注入),以及 IoC(控制反转)容器来控制所有的依赖(这不是必需的,但这是常见的情况),您必须确定,每个可注入依赖项都已在容器中注册,并且 - 可能 - 这通常是一个递归问题。
Exempli gratia,寻找以下 pseudo-code:
// A class which uses injected dependencies
class NeedSomeDependeciesToBeInjected
{
public NeedSomeDependeciesToBeInjected (
IThisIsReallyImportant important,
IThisIsUsefulButNotImportant useful) {}
}
// A complex dependency, which requires other injected dependency
// (So, yes, recursion...)
class ThisIsReallyImportant : IThisIsReallyImportant
{
public ThisIsReallyImportant (
IThisIsRequiredToBecomeImportant required) {}
}
// A dependency, which does not require other injected dependency,
// but is required for another dependency
class ThisIsRequiredToBecomeImportant : IThisIsRequiredToBecomeImportant
{
public ThisIsRequiredToBecomeImportant () {}
}
// A simple dependency, which does not require other injected dependency,
// and is not required for others
class ThisIsUsefulButNotImportant : IThisIsUsefulButNotImportant
{
public ThisIsUsefulButNotImportant () {}
}
class Program
{
private readonly WeaponOfChoiceInIoC container;
public void ConfigureDependencies()
{
container = new WeaponOfChoiceInIoC();
container.Register(IThisIsRequiredToBecomeImportant,
ThisIsRequiredToBecomeImportant);
container.Register(IThisIsReallyImportant,
ThisIsReallyImportant );
container.Register(IThisIsUsefulButNotImportant,
ThisIsUsefulButNotImportant );
}
public void MethodToPlayWithDependencies()
{
var toy = container.GetInstance(NeedSomeDependeciesToBeInjected);
}
}
我正在使用 ASP.NET 核心开发 Web API。当我使用 post 请求执行我的 API 时,在 UnitController 的 Post 方法中的断点之前抛出异常。
异常
Request starting HTTP/1.1 POST http://localhost:5000/api/unit application/json 31 fail: Microsoft.AspNetCore.Server.Kestrel[13] Connection id "0HKVTL9A1LTD4": An unhandled exception was thrown by the application. System.InvalidOperationException: Unable to resolve service for type 'Project.DataAccess.Repository.UnitRepository' while attempting to activate 'Project.Service.UnitService'.
上下文
namespace Project.DataAccess.Library.Interface {
public interface IBaseRepository<M> where M : class, IEntity
{
IEnumerable<M> SelectAll();
M SelectByID(int id);
void Insert(M obj);
void Update(M obj);
void Delete(int id);
void Save();
}
}
namespace Project.DataAccess.Library {
public abstract class BaseRepository<M> : IBaseRepository<M> where M : class, IEntity
{
protected ProjectContext Db { get; }
private DbSet<M> table = null;
protected DbSet<M> Table
{
get
{
return this.table;
}
}
public BaseRepository(ProjectContext dbContext)
{
Db = dbContext;
this.table = Db.Set<M>();
}
public void Delete(int id)
{
M existing = this.SelectByID(id);
if (existing != null)
this.table.Remove(existing);
}
// others methods
}
}
namespace Project.DataAccess.Repository
{
public class UnitRepository : BaseRepository<Unit>, IUnitRepository
{
public UnitRepository(Projectcontext) : base(context) { }
}
}
namespace Project.Service
{
public class UnitService : BaseService<Unit>, IUnitService
{
public UnitService(UnitRepository unitRepository) : base(unitRepository) { }
}
}
namespace AssoManager.Service.Library
{
public abstract class BaseService<M> : IBaseService<M> where M : class, IEntity
{
private IBaseRepository<M> _repository;
public BaseService(IBaseRepository<M> repository)
{
_repository = repository;
}
public IEnumerable<M> GetAll()
{
return this._repository.SelectAll();
}
}
}
namespace Project
{
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
this.DataAccessMySqlConfiguration(services);
this.ConfigureRepository(services);
this.ConfigureServicesUnit(services);
this.ConfigureServicesUser(services);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseMvc();
}
#region Database configuration
public void DataAccessMySqlConfiguration(IServiceCollection services)
{
services.AddDbContext<ProjectContext>(options => options.UseMySQL(Configuration.GetConnectionString("MsSQLConnection")));
}
#endregion
#region DataAccess configuration
public void ConfigureRepository(IServiceCollection services)
{
services.AddScoped<IUnitRepository, UnitRepository>();
services.AddScoped<IUserRepository, UserRepository>();
}
#endregion
#region Services configuration
/// <summary>
/// Is used to add unit services to the container
/// </summary>
public void ConfigureServicesUnit(IServiceCollection services)
{
services.AddTransient<IUnitService, UnitService>();
services.AddTransient<IMeetingService, MeetingService>();
}
/// <summary>
/// Is used to add user services to the container
/// </summary>
public void ConfigureServicesUser(IServiceCollection services)
{
services.AddTransient<IUserService, UserService>();
}
#endregion Services configuration
}
}
namespace Project.Controllers
{
[Route("api/[controller]")]
public class UnitController : Controller
{
private IUnitService UnitService;
public UnitController(IUnitService unitService)
{
UnitService = unitService;
}
// GET api/units
[HttpGet]
public IEnumerable<Unit> Get()
{
return UnitService.GetAll();
}
// GET api/unit/5
[HttpGet("{id}")]
public IActionResult Get(int id)
{
Unit unit;
//->Check
if (id < 1)
return BadRequest();
//->Processing
unit = UnitService.GetByID(id);
if (unit == null)
return NotFound();
return new ObjectResult(unit);
}
// POST api/unit
[HttpPost]
public IActionResult Post([FromBody]Unit unit)
{
//->Check
if (unit == null)
return BadRequest();
//->Processing
UnitService.Create(unit);
return CreatedAtRoute("Get", new { id = unit.Id }, unit);
}
// PUT api/unit/5
[HttpPut("{id}")]
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/unit/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}
版本
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.0",
"type": "platform"
},
"Microsoft.AspNetCore.Mvc": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
"Microsoft.EntityFrameworkCore": "1.0.0",
"MySql.Data.Core": "7.0.4-IR-191",
"MySql.Data.EntityFrameworkCore": "7.0.4-IR-191",
"IdentityServer4": "1.0.0-rc2",
"AssoManager.Domain": "1.0.0-*",
"AssoManager.Service": "1.0.0-*",
"AssoManager.DataAccess": "1.0.0-*"
},
问题
我认为问题可能出在 BaseRepository 和 IBaseRepository 之间的继承上。但我不明白我的错误在哪里。 我该如何纠正这个错误?
感谢您的帮助:),
您正在将 UnitRepository 注册为 IUnitRepository,但请求您的 IoC 解析 UnitRepository。它没有注册,所以它失败了。
尝试让 UnitService 使用 IUnitRepository 而不是 UnitRepository,这应该可以解决问题(请原谅双关语)。
我发现 Callum Bradbury 的答案非常有用(谢谢你,Callum),但我认为更一般的答案可能适用于不同的情况。所以:
当你在给定的 class 中使用 DI(依赖注入),以及 IoC(控制反转)容器来控制所有的依赖(这不是必需的,但这是常见的情况),您必须确定,每个可注入依赖项都已在容器中注册,并且 - 可能 - 这通常是一个递归问题。
Exempli gratia,寻找以下 pseudo-code:
// A class which uses injected dependencies
class NeedSomeDependeciesToBeInjected
{
public NeedSomeDependeciesToBeInjected (
IThisIsReallyImportant important,
IThisIsUsefulButNotImportant useful) {}
}
// A complex dependency, which requires other injected dependency
// (So, yes, recursion...)
class ThisIsReallyImportant : IThisIsReallyImportant
{
public ThisIsReallyImportant (
IThisIsRequiredToBecomeImportant required) {}
}
// A dependency, which does not require other injected dependency,
// but is required for another dependency
class ThisIsRequiredToBecomeImportant : IThisIsRequiredToBecomeImportant
{
public ThisIsRequiredToBecomeImportant () {}
}
// A simple dependency, which does not require other injected dependency,
// and is not required for others
class ThisIsUsefulButNotImportant : IThisIsUsefulButNotImportant
{
public ThisIsUsefulButNotImportant () {}
}
class Program
{
private readonly WeaponOfChoiceInIoC container;
public void ConfigureDependencies()
{
container = new WeaponOfChoiceInIoC();
container.Register(IThisIsRequiredToBecomeImportant,
ThisIsRequiredToBecomeImportant);
container.Register(IThisIsReallyImportant,
ThisIsReallyImportant );
container.Register(IThisIsUsefulButNotImportant,
ThisIsUsefulButNotImportant );
}
public void MethodToPlayWithDependencies()
{
var toy = container.GetInstance(NeedSomeDependeciesToBeInjected);
}
}