当我尝试访问存储库时,收到错误消息:
InvalidOperationException:尝试激活“ software.Notes.Http.Handlers.ShowNote”时,无法解析类型为“ software.Notes.Repositories.NoteRepository”的服务。
所以,我有一个简单的SoftwareContext:
using Microsoft.EntityFrameworkCore;
using software.Contacts.Entities;
using software.Notes.Entities;
namespace software.Core.Entities
{
public class SoftwareContext : DbContext
{
/// <inheritdoc />
/// <summary>
/// Constructor
/// </summary>
public SoftwareContext(DbContextOptions options)
: base(options)
{ }
/// <summary>
/// Contact model
/// </summary>
public DbSet<Contact> Contact { get; set; }
/// <summary>
/// Note model
/// </summary>
public DbSet<Note> Note { get; set; }
}
}
在我的startup.cs文件中实例化的
services.AddDbContext<SoftwareContext>(options =>
options.UseMySql(Configuration.GetConnectionString("DefaultConnection")));
现在,我有一个简单的请求处理程序来显示注释:
using Microsoft.AspNetCore.Mvc;
using software.Notes.Entities;
using software.Notes.Repositories;
namespace software.Notes.Http.Handlers
{
[ApiController]
public class ShowNote : Controller
{
/// <summary>
/// Note Repository
/// </summary>
private readonly NoteRepository _note;
/// <summary>
/// ShowNote constructor
/// </summary>
/// <param name="note"></param>
public ShowNote(NoteRepository note)
{
_note = note;
}
/// <summary>
/// Get the Note via the ID
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
[Route("note/show/{id}")]
public IActionResult init(int id)
{
Note note = _note.Find(id);
if (note != null) {
return Ok(note);
}
return NotFound();
}
}
}
在我的存储库中,我有以下内容:
using System;
using System.Collections.Generic;
using System.Linq;
using software.Core.Entities;
using software.Notes.Entities;
using software.Notes.Repositories.Contracts;
namespace software.Notes.Repositories
{
public abstract class NoteRepository : INoteRepository
{
/// <summary>
/// Database context
/// </summary>
private readonly SoftwareContext _context;
/// <summary>
/// Bind the database to the repo
/// </summary>
/// <param name="context"></param>
protected NoteRepository(SoftwareContext context)
{
_context = context;
}
/// <summary>
/// Create an item from the object
/// </summary>
/// <param name="note"></param>
/// <returns></returns>
public Note Create(Note note)
{
var add = _context.Note.Add(note);
return note;
}
/// <summary>
/// Find a note by the id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public Note Find(int id)
{
return _context.Note.FirstOrDefault(x => x.Id.Equals(id));
}
}
}
是否应该像我当前所做的那样通过存储库的构造函数注入Context?有人可以解释为什么这种方法不起作用,以及使其起作用的正确方法是什么?
完整的异常日志:
System.InvalidOperationException:尝试激活“ software.Notes.Http.Handlers.ShowNote”时,无法解析“ software.Notes.Repositories.NoteRepository”类型的服务。 在Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp,Type type,Type requiredBy,Boolean isDefaultParameterRequired) 在lambda_method(Closure,IServiceProvider,Object []) 在Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider。<> c__DisplayClass4_0.b__0(ControllerContext controllerContext) 在Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider。<> c__DisplayClass5_0.g__CreateController | 0(ControllerContext controllerContext)中。 在Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(状态和下一个,范围和范围,对象和状态,布尔值和isCompleted)处 在Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync() 在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter() 在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext上下文) 在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(状态和下一个,范围和范围,对象和状态,布尔值和已完成) 在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync() 在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync() 在Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext) 在Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext) 在Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext上下文)
答案 0 :(得分:1)
您将必须在.NET Core的IOC容器内添加NoteRepository。有三种方法可以做到这一点: 在startup.cs类中添加
services.AddScoped<INoteRepository, NoteRepository>();
将为每个请求创建一次NoteRepository类的实例
services.AddSingleton <INoteRepository, NoteRepository>();
这意味着NoteRepository类的实例将在请求之间共享
services.AddTransient <INoteRepository, NoteRepository>();
,它将在每次应用程序请求时创建实例。
然后您可以通过控制器的构造函数注入依赖项
[ApiController]
public class ShowNote : Controller
{
private readonly INoteRepository _note;
public ShowNote(INoteRepository note)
{
_note = note;
}
}
答案 1 :(得分:0)
也许您需要将上下文传递给构造函数中的dbcontextoptions?因此,请尝试更改此内容:
public SoftwareContext(DbContextOptions options)
: base(options)
{ }
对此:
public SoftwareContext(DbContextOptions<SoftwareContext> options)
: base(options)
{ }