Не удается разрешить службу для типа при использовании моего репозитория - PullRequest
0 голосов
/ 25 марта 2019

Когда я пытаюсь получить доступ к своему хранилищу, я получаю сообщение об ошибке:

InvalidOperationException: невозможно разрешить службу для типа «software.Notes.Repositories.NoteRepository» при попытке активировать «software.Notes.Http.Handlers.ShowNote».

Итак, у меня есть простой 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));
        }
    }
}

Разве контекст не должен быть введен через конструктор моего репозитория, как я сейчас делаю? Может кто-нибудь объяснить, почему это не работает, и каким будет правильный способ сделать это для работы?

Полный журнал исключений:

System.InvalidOperationException: невозможно разрешить службу для типа «software.Notes.Repositories.NoteRepository» при попытке активировать «software.Notes.Http.Handlers.ShowNote». в Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService (IServiceProvider sp, тип Type, тип requiredBy, логическое значение isDefaultParameterRequired) в lambda_method (Закрытие, IServiceProvider, Объект []) в 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 (State & next, Scope & scope, Object & state, Boolean & 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 (State & next, Scope & scope, Object & state, Boolean & isCompleted) в 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 ]

1 голос
/ 25 марта 2019

Вам нужно будет добавить свой NoteRepository в контейнер IOC .NET Core.Есть три способа сделать это: в классе 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;
    }
}
0 голосов
/ 25 марта 2019

может быть, вам нужно передать контекст dbcontextoptions в конструкторе?Поэтому попробуйте изменить это:

public SoftwareContext(DbContextOptions options)
        : base(options)
    { }

на это:

public SoftwareContext(DbContextOptions<SoftwareContext> options)
        : base(options)
    { }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...