asp.net MVC6 프로젝트에서 작업 중이며 웹 API에 문제가 있습니다. 특정 API를 테스트 할 때 내부 오류 (500 http 응답 코드)가 발생합니다.
조사한 결과 서비스에서 얻으려는 개체를 등록하지 않았다는이 오류를 발견했습니다.
'DotnetProject.BusinessLayer.Implementation.QuerryHandlers.GetTestByIdQueryHandler'유형에 대한 서비스가 등록되지 않았습니다.
문제는 내 컨트롤러가 [FromServices]
구문을 사용 하여 IoC 컨테이너에서 특정 개체를 요청하고 해당 서비스를 등록하지 않았다는 예외가 발생한다는 것입니다.
서비스에서 해당 개체를 요청하지 않으면 더 이상 내부 오류가 발생하지 않습니다.
[FromServices]
구문이 있는 객체를 요청하는 모든 API 함수에 대해 해당 오류가 발생 합니다. 그래서 문제는 어딘가에 있지만 알아낼 수 없습니다.
내 컨트롤러 클래스는 다음과 같습니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DotnetProject.BusinessLayer.Interfaces;
using DotnetProject.DataLayer.Domain_Entities;
using DotnetProject.DataLayer.Interfaces;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using DotnetProject.BusinessLayer.Implementation.Queries.Users;
using DotnetProject.BusinessLayer.Implementation.QuerryHandlers.Users;
using DotnetProject.BusinessLayer.Implementation.QuerryResults.Users;
using DotnetProject.BusinessLayer.Implementation.Queries;
using DotnetProject.BusinessLayer.Implementation.QuerryHandlers;
using DotnetProject.BusinessLayer.Implementation.Commands.Users;
using DotnetProject.BusinessLayer.Implementation.CommandHandlers.Users;
using DotnetProject.BusinessLayer.Implementation.Commands;
using DotnetProject.BusinessLayer.Implementation.CommandHandlers;
// For more information on enabling Web API for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
namespace DotnetProject.Controllers.Api
{
[Route("api/[controller]")]
[AllowAnonymous]
public class TestController : Controller
{
private ITestRepository testRepository;
private ITestService testService;
public TestController(ITestRepository _testRepository,ITestService _testService)
{
testRepository = _testRepository;
testService = _testService;
}
// GET: api/values
[HttpGet]
[Route("getAllTests")]
public GetAllTestsQueryResult GetAll([FromServices] GetAllTestsQueryHandler handler)
{
return handler.Retrieve(new GetAllTestsQuery());
}
// GET api/values/5
[HttpGet]
[Route("getTest")]
public GetTestByIdQueryResult GetTest([FromServices]GetTestByIdQueryHandler handler,GetTestByIdQuery query)
{
return handler.Retrieve(query);
}
// DELETE api/values/5
[HttpPost]
[Route("delete")]
public void Delete(DeleteTestCommand command,[FromServices]DeleteTestHandler handler)
{
handler.Execute(command);
}
[HttpPost]
[Route("add")]
public void AddTest(AddTestCommand command, [FromServices]AddTestHandler handler) {
handler.Execute(command);
}
[HttpPost]
[Route("update")]
public void UpdateTest(UpdateTestCommand command,[FromServices]UpdateTestHandler handler) {
handler.Execute(command);
}
}
}
다음은 "등록되지 않음"으로 표시되는 개체 예입니다.
using AT.Core.Cqrs;
using DotnetProject.BusinessLayer.Implementation.Commands.Users;
using DotnetProject.DataLayer;
using DotnetProject.DataLayer.Domain_Entities;
using DotnetProject.DataLayer.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace DotnetProject.BusinessLayer.Implementation.CommandHandlers.Users
{
public class AddTestHandler : ICommandHandler<AddTestCommand>
{
private ITestRepository _testRepository;
public AddTestHandler(ITestRepository testRepository)
{
_testRepository = testRepository;
}
public void Execute(AddTestCommand newTest)
{
Test test = new Test();
test.Id = newTest.Id;
test.QuestionList = newTest.QuestionList;
test.TestDuration = newTest.TestDuration;
_testRepository.Add(test);
}
}
}
다음은 시작 파일의 ConfigureServices 함수입니다.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);
services.AddScoped<IUserService, UserService>();
services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<ITestRepository, TestRepository>();
services.AddScoped<ITestService, TestService>();
services.AddScoped<IRoleService, RoleService>();
services.AddScoped<IRoleRepository, RoleRepository>();
services.AddScoped<ICommandHandler<DeleteUserCommand>, DeleteUserHandler>();
services.AddScoped<ICommandHandler<UpdateUserCommand>,UpdateUserHandler>();
services.AddScoped<ICommandHandler<AddUserCommand>, AddUserHandler>();
services.AddScoped<ICommandHandler<DeleteTestCommand>, DeleteTestHandler>();
services.AddScoped<ICommandHandler<UpdateTestCommand>, UpdateTestHandler>();
services.AddScoped<ICommandHandler<AddTestCommand>, AddTestHandler>();
services.AddScoped<IQueryHandler<GetAllTestsQuery,GetAllTestsQueryResult>,GetAllTestsQueryHandler>();
services.AddScoped<IQueryHandler<GetTestByIdQuery, GetTestByIdQueryResult>,GetTestByIdQueryHandler>();
services.AddScoped<IQueryHandler<GetAllUsersQuery, GetAllUsersQueryResult>, GetAllUsersQueryHandler>();
services.AddScoped<IQueryHandler<GetUserByIdQuery, GetUserByIdQueryResult>, GetUserByIdQueryHandler>();
services.AddDbContext<ApplicationContext>();
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
config.OutputFormatters.Clear();
config.OutputFormatters.Add(new JsonOutputFormatter(new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
}, ArrayPool<char>.Shared));
});
services.AddMvc();
// Inject an implementation of ISwaggerProvider with defaulted settings applied
services.AddSwaggerGen();
}
에 기초하여 ConfigureServices
, 예에서 GetTestByIdQueryHandler was not registered
. 인터페이스 IQueryHandler<GetTestByIdQuery, GetTestByIdQueryResult>
가 등록되어있을 때 GetTestByIdQueryHandler
. 차이가 있고 쉽게 오해됩니다.
DI 컨테이너는 GetTestByIdQueryHandler
직접 해결하라는 요청을받을 때 수행 할 작업을 인식하지 못합니다 .
따라서 서비스를
services.AddScoped<GetTestByIdQueryHandler, GetTestByIdQueryHandler>();
처리 방법을 알 수 있도록 GetTestByIdQueryHandler
또는
DI 컨테이너가 인식하는 유형을 호출하도록 조치를 업데이트하십시오.
// GET api/values/5
[HttpGet]
[Route("getTest")]
public GetTestByIdQueryResult GetTest([FromServices]IQueryHandler<GetTestByIdQuery, GetTestByIdQueryResult> handler,GetTestByIdQuery query)
{
return handler.Retrieve(query);
}
이상적으로 인터페이스는 몇 가지 규칙을 따라야합니다.
public interface IGetTestByIdQueryHandler : IQueryHandler<GetTestByIdQuery, GetTestByIdQueryResult> {
}
public class GetTestByIdQueryHandler : IGetTestByIdQueryHandler {
//...
}
그에 따라 등록
services.AddScoped<IGetTestByIdQueryHandler, GetTestByIdQueryHandler>();
그리고 깨끗하게 해결
// GET api/test/getTest
[HttpGet]
[Route("getTest")]
public GetTestByIdQueryResult GetTest([FromServices]IGetTestByIdQueryHandler handler, GetTestByIdQuery query) {
return handler.Retrieve(query);
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다