Criei um aplicativo .NET Core MVC e usei o Dependency Injection and Repository Pattern para injetar um repositório no meu controlador. No entanto, estou recebendo um erro:
InvalidOperationException: não foi possível resolver o serviço para o tipo 'WebApplication1.Data.BloggerRepository' ao tentar ativar 'WebApplication1.Controllers.BlogController'.
Modelo (Blog.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; }
}
}
Repositório (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);
}
}
}
Startup.cs (código relevante)
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>();
}
Controlador (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);
}
}
}
Não tenho certeza do que estou fazendo de errado. Alguma ideia?
Respostas:
A exceção diz que não pode resolver o serviço
WebApplication1.Data.BloggerRepository
porque o construtor no seu controlador está solicitando a classe concreta em vez da interface. Então, basta mudar isso:fonte
HttpContextAccessor
classe, descobriu que eu precisava doIHttpContextAccessor
Corri para esse problema porque na configuração da injeção de dependência estava faltando uma dependência de um repositório que é uma dependência de um controlador:
fonte
No meu caso, eu estava tentando fazer injeção de dependência para um objeto que exigia argumentos construtores. Nesse caso, durante a inicialização, apenas forneci os argumentos do arquivo de configuração, por exemplo:
fonte
Eu estava tendo um problema diferente e, sim, o construtor parametrizado para o meu controlador já foi adicionado com a interface correta. O que eu fiz foi algo direto. Acabei de ir ao meu
startup.cs
arquivo, onde pude ver uma chamada para registrar o método.No meu caso, esse
Register
método estava em uma classe separadaInjector
. Então eu tive que adicionar minhas interfaces recém-introduzidas lá.Se você vir, o parâmetro para esta função é
this IServiceCollection
Espero que isto ajude.
fonte
Somente se alguém tiver a mesma situação que eu, estou fazendo um tutorial do EntityFramework com o banco de dados existente, mas quando o novo contexto do banco de dados é criado nas pastas de modelos, precisamos atualizar o contexto na inicialização, mas não apenas nos serviços. AddDbContext, mas AddIdentity também se você tiver autenticação de usuários
fonte
Você precisa adicionar um novo serviço para
DBcontext
na inicializaçãoPadrão
Adicione isso
fonte
Você esqueceu de adicionar "services.AddScoped" no
ConfigureServices
método de inicialização .fonte
Eu peguei esse problema por causa de um erro bobo. Eu tinha esquecido de conectar meu procedimento de configuração de serviço para descobrir controladores automaticamente no aplicativo ASP.NET Core.
A adição deste método resolveu:
fonte
Eu tive que adicionar esta linha no ConfigureServices para funcionar.
fonte
Eu estava ficando abaixo da exceção
Como eu queria registrar o Factory para criar instâncias da classe derivada DbContext IBlogContextFactory e usar o método Create para instanciar a instância do Contexto do Blog para que eu possa usar o padrão abaixo junto com a injeção de dependência e também usar simulação para testes de unidade.
o padrão que eu queria usar é
Mas, em vez do novo BloggingContext (), quero injetar fábrica via construtor, como na classe BlogController abaixo
aqui está o meu código de registro de serviço
e abaixo estão meus modelos e classes de fábrica
----- Para corrigir isso no projeto .net Core MVC - fiz abaixo as alterações no registro de dependência
Em resumo, o desenvolvedor do núcleo .net é responsável por injetar a função de fábrica, a qual, no caso do Unity e do .Net Framework, foi cuidada.
fonte
Esse problema ocorre porque você não registrou o componente de acesso a dados com a interface criada para ele. Tente usar da seguinte maneira
fonte
Se você estiver usando o AutoFac e obtendo esse erro, adicione uma instrução "Como" para especificar o serviço que a implementação concreta implementa.
Ou seja. você deve escrever:
ao invés de
fonte
ohh, obrigado @kimbaudi, eu segui esses detalhes
https://dotnettutorials.net/lesson/generic-repository-pattern-csharp-mvc/
e obteve o mesmo erro que o seu. Mas depois de ler seu código, descobri que minha solução estava adicionando
no método ConfigureServices no arquivo StartUp.cs =))
fonte
A resolução de um serviço é feita antes mesmo de o código da classe ser alcançado, portanto, precisamos verificar nossas injeções de dependência.
No meu caso eu adicionei
em StartupExtensions.cs
fonte
Adicionar services.AddSingleton (); no método ConfigureServices do arquivo Startup.cs do seu projeto.
Para mais detalhes, visite este URL: https://www.youtube.com/watch?v=aMjiiWtfj2M
para Todos os métodos (por exemplo, AddSingleton vs AddScoped vs AddTransient) Visite este URL: https://www.youtube.com/watch?v=v6Nr7Zman_Y&list=PL6n9fhu94yhVkdrusLaQsfERmL_Jh4XmU&index=44 )
fonte
Eu tive o mesmo problema e descobri que meu código estava usando a injeção antes de ser inicializada.
Sei que não tem nada a ver com a pergunta, mas desde que fui enviada para esta página, acho que pode ser útil para outra pessoa.
fonte
Eu troquei
Com
E funcionou para mim.
fonte
Eu recebi esse erro porque declarei uma variável (acima do método ConfigureServices) do tipo que era meu contexto. Eu tinha:
Não tenho certeza do que estava pensando. Eu sei que é legal fazer isso se você estiver passando um parâmetro para o método Configure.
fonte
Eu recebi o erro: "Incapaz de resolver a dependência xxxxxxxx para todas as versões do núcleo .net". Eu tentei tudo disponível na internet e fiquei preso por dias. A única solução que encontrei foi adicionar o arquivo nuget.config no projeto e, em seguida, usar a restauração do dotnet para fazê-lo funcionar.
Conteúdo do arquivo nuget.config:
fonte