使用我的存储库时无法解析服务类型

时间:2019-03-25 01:17:45

标签: c# asp.net-mvc asp.net-web-api asp.net-core

当我尝试访问存储库时,收到错误消息:

  

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上下文)

2 个答案:

答案 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)
    { }