Δημιούργησα μια εφαρμογή .NET Core MVC και χρησιμοποίησα το Dependency Injection και το Repository Pattern για να εγχύσω ένα αποθετήριο στον ελεγκτή μου. Ωστόσο, λαμβάνω ένα σφάλμα:
InvalidOperationException: WebApplication1.Data.BloggerRepository' κατά την προσπάθεια ενεργοποίησης του 'WebApplication1.Controllers.BlogController'.
Μοντέλο (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; }
}
}
Αποθετήριο (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 (σχετικός κώδικας)
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);
}
}
}
Δεν είμαι σίγουρος τι κάνω λάθος. Καμία ιδέα;
Η εξαίρεση λέει ότι δεν μπορεί να επιλύσει την υπηρεσία για το WebApplication1.Data.BloggerRepository
επειδή ο κατασκευαστής στον ελεγκτή σας ζητά την συγκεκριμένη κλάση αντί για τη διασύνδεση. Οπότε απλά αλλάξτε το αυτό:
public BlogController(IBloggerRepository repository)
// ^
// Add this!
{
_repository = repository;
}
Στην περίπτωσή μου προσπαθούσα να κάνω dependency injection για ένα αντικείμενο που απαιτούσε ορίσματα κατασκευαστή. Σε αυτή την περίπτωση, κατά τη διάρκεια της Εκκίνησης παρείχα απλώς τα ορίσματα από το αρχείο ρυθμίσεων, για παράδειγμα:
var config = Configuration.GetSection("subservice").Get<SubServiceConfig>();
services.AddScoped<ISubService>(provider => new SubService(config.value1, config.value2));
Μόνο αν κάποιος έχει την ίδια κατάσταση όπως εγώ, κάνω ένα σεμινάριο του EntityFramework με υπάρχουσα βάση δεδομένων, αλλά όταν δημιουργείται το νέο πλαίσιο βάσης δεδομένων στους φακέλους μοντέλων, πρέπει να ενημερώσουμε το πλαίσιο στην εκκίνηση, αλλά όχι μόνο στο services.AddDbContext αλλά και στο AddIdentity αν έχετε έλεγχο ταυτότητας χρηστών
services.AddDbContext<NewDBContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<NewDBContext>()
.AddDefaultTokenProviders();