[C#] ASP.NET Core Dependency Injection 오류 : 정품 인증을 시도하는 동안 형식에 대한 서비스를 확인할 수 없습니다

.NET Core MVC 응용 프로그램을 만들고 Dependency Injection 및 Repository Pattern을 사용하여 리포지토리를 컨트롤러에 주입합니다. 그러나 오류가 발생합니다.

InvalidOperationException : ‘WebApplication1.Controllers.BlogController’를 활성화하는 중 ‘WebApplication1.Data.BloggerRepository’유형의 서비스를 분석 할 수 없습니다.

모델 (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;
}


답변

종속성 주입 설정에서 컨트롤러의 종속성 인 저장소의 종속성이 없기 때문에이 문제가 발생했습니다.

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


답변

제 경우에는 생성자 인수가 필요한 객체에 대한 종속성 주입을 시도했습니다. 이 경우 시작하는 동안 구성 파일에서 인수를 제공했습니다. 예를 들면 다음과 같습니다.

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

도움이 되었기를 바랍니다.


답변

누구든지 나와 같은 상황이있는 경우에만 기존 데이터베이스로 EntityFramework 자습서를 수행하고 있지만 모델 폴더에서 새 데이터베이스 컨텍스트를 만들 때 서비스뿐만 아니라 시작시 컨텍스트를 업데이트해야합니다. 사용자 인증이있는 경우 AddDbContext이지만 AddIdentity도

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

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


답변

DBcontext시작시 새 서비스를 추가해야합니다

기본

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

이거 추가 해봐

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


답변

Public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IEventRepository, EventRepository>();
}

시작 ConfigureServices방법 에 “services.AddScoped”를 추가하는 것을 잊었습니다 .