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);
}
}
}
Я не уверен, что я делаю неправильно. Есть идеи?
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