Utworzyłem aplikację .NET Core MVC i do wstrzykiwania repozytorium do mojego kontrolera używam Dependency Injection and Repository Pattern. Jednak pojawia się błąd:
InvalidOperationException: Nie można rozwiązać usługi typu „WebApplication1.Data.BloggerRepository” podczas próby aktywacji „WebApplication1.Controllers.BlogController”.
Model (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; }
}
}
Repozytorium (IBloggerRepository.cs i 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 (odpowiedni kod)
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>();
}
Kontroler (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);
}
}
}
Nie jestem pewien, co robię źle. Jakieś pomysły?
Odpowiedzi:
Wyjątek mówi, że nie może rozwiązać usługi,
WebApplication1.Data.BloggerRepository
ponieważ konstruktor w kontrolerze prosi o konkretną klasę zamiast interfejsu. Po prostu zmień to:źródło
HttpContextAccessor
klasy, okazało się, że potrzebowałemIHttpContextAccessor
Natknąłem się na ten problem, ponieważ w konfiguracji wstrzykiwania zależności brakowało zależności repozytorium, która jest zależnością kontrolera:
źródło
W moim przypadku próbowałem wykonać wstrzyknięcie zależności dla obiektu, który wymagał argumentów konstruktora. W tym przypadku podczas uruchamiania podałem tylko argumenty z pliku konfiguracyjnego, na przykład:
źródło
Miałem inny problem i tak, sparametryzowany konstruktor mojego kontrolera został już dodany z odpowiednim interfejsem. To, co zrobiłem, było proste. Po prostu idę do mojego
startup.cs
pliku, w którym mogę zobaczyć metodę rejestracji.W moim przypadku ta
Register
metoda była w osobnej klasieInjector
. Musiałem więc tam dodać moje nowo wprowadzone interfejsy.Jeśli widzisz, parametrem tej funkcji jest
this IServiceCollection
Mam nadzieję że to pomoże.
źródło
Tylko jeśli ktoś ma taką samą sytuację jak ja, robię tutorial EntityFramework z istniejącą bazą danych, ale kiedy nowy kontekst bazy danych jest tworzony w folderach modeli, musimy zaktualizować kontekst podczas uruchamiania, ale nie tylko w usługach. AddDbContext, ale także AddIdentity, jeśli masz uwierzytelnianie użytkowników
źródło
Musisz dodać nową usługę dla
DBcontext
podczas uruchamianiaDomyślna
Dodaj
źródło
Zapomniałeś dodać „services.AddScoped” w
ConfigureServices
metodzie uruchamiania .źródło
Dostałem ten problem z powodu dość głupiej pomyłki. Zapomniałem zawiesić procedury konfiguracji usługi, aby automatycznie wykrywać kontrolery w aplikacji ASP.NET Core.
Dodanie tej metody rozwiązało to:
źródło
Musiałem dodać tę linię do ConfigureServices, aby działać.
źródło
Byłem poniżej wyjątku
Ponieważ chciałem zarejestrować Factory, aby utworzyć instancje klasy pochodnej DbContext IBlogContextFactory i użyć metody Create, aby utworzyć instancję instancji Blog Context, dzięki czemu będę mógł korzystać z poniższego wzorca wraz z zależnością Wstrzykiwanie, a także używać kpiny do testowania jednostkowego.
wzór, którego chciałem użyć, to
Ale zamiast nowego BloggingContext () chcę wstrzyknąć fabrykę za pomocą konstruktora, jak w poniższej klasie BlogController
oto mój kod rejestracyjny usługi
a poniżej są moje modele i klasy fabryczne
----- Aby to naprawić w projekcie .NET Core MVC - Wprowadziłem poniższe zmiany dotyczące rejestracji zależności
W skrócie, deweloper rdzenia .net jest odpowiedzialny za wstrzyknięcie funkcji fabryki, co w przypadku Unity i .Net Framework zostało załatwione.
źródło
Ten problem jest spowodowany tym, że komponent dostępu do danych nie został zarejestrowany w interfejsie dla niego napisanym. Spróbuj użyć w następujący sposób
źródło
Jeśli używasz funkcji AutoFac i pojawia się ten błąd, należy dodać instrukcję „As”, aby określić usługę, którą implementuje konkretna implementacja.
To znaczy. powinieneś napisać:
zamiast
źródło
och, dziękuję @kimbaudi, śledziłem te tutki
https://dotnettutorials.net/lesson/generic-repository-pattern-csharp-mvc/
i dostałem ten sam błąd co twój. Ale po przeczytaniu kodu dowiedziałem się, że moje rozwiązanie zostało dodane
do metody ConfigureServices w pliku StartUp.cs =))
źródło
Rozwiązanie usługi odbywa się nawet przed osiągnięciem kodu klasy, dlatego musimy sprawdzić nasze zastrzyki zależności.
W moim przypadku dodałem
w StartupExtensions.cs
źródło
Dodaj services.AddSingleton (); w metodzie ConfigureServices pliku Startup.cs twojego projektu.
Aby uzyskać więcej informacji, odwiedź ten adres URL: https://www.youtube.com/watch?v=aMjiiWtfj2M
dla wszystkich metod (tj. AddSingleton vs AddScoped vs AddTransient) Odwiedź ten adres URL: https://www.youtube.com/watch?v=v6Nr7Zman_Y&list=PL6n9fhu94yhVkdrusLaQsfERmL_Jh4XmU&index=44 )
źródło
Miałem ten sam problem i dowiedziałem się, że mój kod używał zastrzyku przed jego zainicjowaniem.
Wiem, że to nie ma nic wspólnego z tym pytaniem, ale ponieważ zostałem wysłany na tę stronę, doszedłem do wniosku, że przyda mi się ktoś inny.
źródło
Wymieniłem
Z
I zadziałało dla mnie.
źródło
Wystąpił ten błąd, ponieważ zadeklarowałem zmienną (powyżej metody ConfigureServices) typu, która była moim kontekstem. Miałem:
Nie jestem pewien, co myślałem. Wiem, że jest to legalne, jeśli przekazujesz parametr do metody Konfiguruj.
źródło
Wystąpił błąd: „nie można rozwiązać zależności xxxxxxxx dla wszystkich wersji rdzenia .net”. Próbowałem wszystkiego dostępnego w Internecie i utknąłem na kilka dni. Jedynym rozwiązaniem, jakie wymyśliłem, było dodanie pliku nuget.config do projektu, a następnie użycie przywracania dotnet, aby działało.
Zawartość pliku nuget.config:
źródło