ASP.NET ошибка внедрения основных зависимостей: не удается разрешить службу для типа при попытке активации



Я создал приложение .NET Core MVC и использую инъекцию зависимостей и шаблон репозитория для внедрения репозитория в мой контроллер. Однако, я получаю сообщение об ошибке:




InvalidOperationException: не удается разрешить службу для типа ' WebApplication1.Данные.BloggerRepository 'при попытке активировать' WebApplication1.Контроллеры.BlogController'.




Модель (Блог.cs)



namespace WebApplication1.Models
{
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
}


DbContext (BloggingContext.cs)



using Microsoft.EntityFrameworkCore;
using WebApplication1.Models;

namespace WebApplication1.Data
{
public class BloggingContext : DbContext
{
public BloggingContext(DbContextOptions<BloggingContext> options)
: base(options)
{ }
public DbSet<Blog> Blogs { get; set; }
}
}


Репозиторий (IBloggerRepository.cs & BloggerRepository.cs)



using System;
using System.Collections.Generic;
using WebApplication1.Models;

namespace WebApplication1.Data
{
internal interface IBloggerRepository : IDisposable
{
IEnumerable<Blog> GetBlogs();

void InsertBlog(Blog blog);

void Save();
}
}

using System;
using System.Collections.Generic;
using System.Linq;
using WebApplication1.Models;

namespace WebApplication1.Data
{
public class BloggerRepository : IBloggerRepository
{
private readonly BloggingContext _context;

public BloggerRepository(BloggingContext context)
{
_context = context;
}

public IEnumerable<Blog> GetBlogs()
{
return _context.Blogs.ToList();
}

public void InsertBlog(Blog blog)
{
_context.Blogs.Add(blog);
}

public void Save()
{
_context.SaveChanges();
}

private bool _disposed;

protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_context.Dispose();
}
}
_disposed = true;
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}


Автозагрузка.КС (соответствующий код)



public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<BloggingContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

services.AddScoped<IBloggerRepository, BloggerRepository>();

services.AddMvc();

// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
}


Контроллер (BlogController.cs)



using System.Linq;
using Microsoft.AspNetCore.Mvc;
using WebApplication1.Data;
using WebApplication1.Models;

namespace WebApplication1.Controllers
{
public class BlogController : Controller
{
private readonly IBloggerRepository _repository;

public BlogController(BloggerRepository repository)
{
_repository = repository;
}

public IActionResult Index()
{
return View(_repository.GetBlogs().ToList());
}

public IActionResult Create()
{
return View();
}

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Blog blog)
{
if (ModelState.IsValid)
{
_repository.InsertBlog(blog);
_repository.Save();
return RedirectToAction("Index");
}
return View(blog);
}
}
}


Я не уверен, что я делаю неправильно. Есть идеи?

687   9  

9 ответов:

исключение говорит, что он не может разрешить службу для WebApplication1.Data.BloggerRepository потому что конструктор на контроллере запрашивает конкретный класс вместо интерфейса. Так что просто измените это:

public BlogController(IBloggerRepository repository)
//                    ^
//                    Add this!
{
    _repository = repository;
}

только если у кого-то такая же ситуация, как у меня, я делаю учебник EntityFramework с существующей базой данных, но когда новый контекст базы данных создается в папках models, нам нужно обновить контекст при запуске, но не только в службах.AddDbContext но AddIdentity тоже, если у вас есть аутентификация пользователей

services.AddDbContext<NewDBContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<NewDBContext>()
                .AddDefaultTokenProviders();

в моем случае я пытался сделать инъекцию зависимостей для объекта, который требует аргументов конструктора. В этом случае во время запуска я просто предоставил аргументы из файла конфигурации, например:

var config = Configuration.GetSection("subservice").Get<SubServiceConfig>();
services.AddScoped<ISubService>(provider => new SubService(config.value1, config.value2));

у меня была другая проблема, и да параметризованный конструктор для моего контроллера уже был добавлен с правильным интерфейсом. То, что я сделал, было чем-то простым. Я просто иду к своему startup.cs файл, где я мог видеть вызов метода регистрации.

public void ConfigureServices(IServiceCollection services)
{
   services.Register();
}

в моем случае это Register метод был в отдельном классе Injector. Поэтому мне пришлось добавить туда свои новые интерфейсы.

public static class Injector
{
    public static void Register(this IServiceCollection services)
    {
        services.AddTransient<IUserService, UserService>();
        services.AddTransient<IUserDataService, UserDataService>();
    }
}

если вы видите, параметр этой функции this IServiceCollection

надеюсь, что это помогает.

Я получил эту проблему из-за довольно глупой ошибки. Я забыл подключить процедуру настройки службы, чтобы автоматически обнаружить контроллеры в системе. ASP.NET основное применение.

добавление этого метода решило его:

// Add framework services.
            services.AddMvc()
                    .AddControllersAsServices();      // <---- Super important

Если вы используете AutoFac и получаете эту ошибку, вы должны добавить оператор "As", чтобы указать службу, которую реализует конкретная реализация.

Ie. вы должны написать:

containerBuilder.RegisterType<DataService>().As<DataService>();

вместо

containerBuilder.RegisterType<DataService>();

я столкнулся с этой проблемой, потому что в настройке инъекции зависимостей мне не хватало зависимости репозитория, которая является зависимостью контроллера:

services.AddScoped<IDependencyOne, DependencyOne>();    <-- I was missing this line!
services.AddScoped<IDependencyTwoThatIsDependentOnDependencyOne, DependencyTwoThatIsDependentOnDependencyOne>();

нужно добавить новый сервис для DBcontext стартап

по умолчанию

services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));

добавить

services.AddDbContext<NewDBContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("NewConnection")));

Мне пришлось добавить эту строку в ConfigureServices для того, чтобы работать.

услуги.AddSingleton ();

Comments

    Ничего не найдено.