请注意,我使用的是Autofac,但是当我运行API并使用此URL与Postman进行检查时,:
http://localhost:1234/api/calculations/corpname&51&114&1045
我收到此错误:
{
"message": "An error has occurred.",
"exceptionMessage": "An error occurred when trying to create a controller of type 'CalculationsController'. Make sure that the controller has a parameterless public constructor.",
"exceptionType": "System.InvalidOperationException",
"stackTrace": " at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)rn at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)rn at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()",
"innerException": {
"message": "An error has occurred.",
"exceptionMessage": "An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = CalculationsController (ReflectionActivator), Services = [MyAppTools.Controllers.CalculationsController], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope ---> An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = CalcRepository (ReflectionActivator), Services = [MyAppTools.Data.ICalcRepository], Lifetime = Autofac.Core.Lifetime.MatchingScopeLifetime, Sharing = Shared, Ownership = OwnedByLifetimeScope ---> None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'MyAppTools.Data.CalcRepository' can be invoked with the available services and parameters:rnCannot resolve parameter 'MyAppTools.Data.ICalcContext context' of constructor 'Void .ctor(MyAppTools.Data.ICalcContext)'. (See inner exception for details.) (See inner exception for details.)",
"exceptionType": "Autofac.Core.DependencyResolutionException",
"stackTrace": " at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)rn at Autofac.Core.Resolving.InstanceLookup.Execute()rn at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters)rn at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters)rn at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)rn at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)rn at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable`1 parameters)rn at Autofac.ResolutionExtensions.ResolveOptional(IComponentContext context, Type serviceType)rn at Autofac.Integration.WebApi.AutofacWebApiDependencyScope.GetService(Type serviceType) in C:\projects\autofac-webapi\src\Autofac.Integration.WebApi\AutofacWebApiDependencyScope.cs:line 76rn at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)rn at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)",
"innerException": {
"message": "An error has occurred.",
"exceptionMessage": "An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = CalcRepository (ReflectionActivator), Services = [MyAppTools.Data.ICalcRepository], Lifetime = Autofac.Core.Lifetime.MatchingScopeLifetime, Sharing = Shared, Ownership = OwnedByLifetimeScope ---> None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'MyAppTools.Data.CalcRepository' can be invoked with the available services and parameters:rnCannot resolve parameter 'MyAppTools.Data.ICalcContext context' of constructor 'Void .ctor(MyAppTools.Data.ICalcContext)'. (See inner exception for details.)",
"exceptionType": "Autofac.Core.DependencyResolutionException",
"stackTrace": " at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)rn at Autofac.Core.Resolving.InstanceLookup.<Execute>b__5_0()rn at Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(Guid id, Func`1 creator)rn at Autofac.Core.Resolving.InstanceLookup.Execute()rn at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters)rn at Autofac.Core.Resolving.InstanceLookup.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)rn at Autofac.Core.Activators.Reflection.AutowiringParameter.<>c__DisplayClass0_0.<CanSupplyValue>b__0()rn at Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()rn at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)rn at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)",
"innerException": {
"message": "An error has occurred.",
"exceptionMessage": "None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'MyAppTools.Data.CalcRepository' can be invoked with the available services and parameters:rnCannot resolve parameter 'MyAppTools.Data.ICalcContext context' of constructor 'Void .ctor(MyAppTools.Data.ICalcContext)'.",
"exceptionType": "Autofac.Core.DependencyResolutionException",
"stackTrace": " at Autofac.Core.Activators.Reflection.ReflectionActivator.GetValidConstructorBindings(IComponentContext context, IEnumerable`1 parameters)rn at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)rn at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)"
}
}
}
}
当我调查时,我发现了这些网站:
Autofac 和 ASP .Net MVC 4 Web API
但是我有一个用于计算控制器的公共无参数构造函数:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using AutoMapper;
using MyAppTools.Data;
using MyAppTools.Models;
namespace MyAppTools.Controllers
{
public class CalculationsController : ApiController
{
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
private readonly IMapper _mapper;
private readonly ICalcRepository _repository;
private readonly IMyModelUserRepository _myModelRepository;
public CalculationsController()
{
}
public CalculationsController(ICalcRepository repository, IMyModelUserRepository myModelRepository, IMapper mapper)
{
_repository = repository;
_myModelRepository = myModelRepository;
_mapper = mapper;
}
public async Task<IHttpActionResult> Get()
{
try
{
var result = await _repository.GetAllCalculationsAsync();
if (result == null) return NotFound();
// Mapping
// This centralizes all of the config
var mappedResult = _mapper.Map<IEnumerable<CalculationModel>>(result);
return Ok(mappedResult);
}
catch (Exception ex)
{
Logger.Error(ex);
// Be careful about returning exception here
return InternalServerError();
}
}
[Route("{username}/{password}/{latitude}/{longitude}/{depth}")]
public async Task<IHttpActionResult> Get(string username, string password, double latitude, double longitude, double depth)
{
try
{
var result = await _repository.GetCalculationAsync(username, password, latitude, longitude, depth);
if (result == null) return NotFound();
// Mapping
// This centralizes all of the config
var mappedResult = _mapper.Map<IEnumerable<CalculationModel>>(result);
return Ok(mappedResult);
}
catch (Exception ex)
{
Logger.Error(ex);
// Be careful about returning exception here
return InternalServerError();
}
}
}
}
到目前为止,我已经在这里检查了解决方案:
Autofac 和 ASP .Net MVC 4 Web API https://www.nopcommerce.com/boards/t/38102/none-of-the-constructors-found-with-autofaccoreactivatorsreflectiondefaultconstructorfinder-on-type.aspx
但我认为这不适用于我的情况。
这是我的注册服务:
public class AutofacConfig
{
public static void Register()
{
var bldr = new ContainerBuilder();
var config = GlobalConfiguration.Configuration;
bldr.RegisterApiControllers(Assembly.GetExecutingAssembly());
RegisterServices(bldr);
bldr.RegisterWebApiFilterProvider(config);
bldr.RegisterWebApiModelBinderProvider();
var container = bldr.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}
private static void RegisterServices(ContainerBuilder bldr)
{
var config = new MapperConfiguration(cfg => { cfg.AddProfile(new CalculationMappingProfile()); });
bldr.RegisterInstance(config.CreateMapper())
.As<IMapper>()
.SingleInstance();
bldr.RegisterType<CalcContext>()
.InstancePerRequest();
bldr.RegisterType<CalcRepository>()
.As<ICalcRepository>()
.InstancePerRequest();
bldr.RegisterType<MyModelUserRepository>()
.As<IMyModelUserRepository>()
.InstancePerRequest();
}
}
这是我认为我收到错误的函数:
public async Task<double[]> GetCalculationAsync(string username, string password, double latitude,
double longitude, double depth, bool includeWellRuns = false)
{
Calculation calc = new Calculation();
double[] results = null;
try
{
var user = _context.MyModels.FirstOrDefault(e => e.UserName == username);
if (user?.LicenseKey == password)
{
myModelServiceClient client = new myModelServiceClient("NetTcpBinding_IMyModelService");
results = client.GetMyModel(latitude, longitude, depth, DateTime.Now.Day,
DateTime.Now.Month, DateTime.Now.Year, DateTime.Now.Year, calc.UseGeoid, calc.UseDecimalYear);
calc.Inclination = Convert.ToString(results[0]);
calc.Declination = Convert.ToString(results[1]);
calc.TotalField = Convert.ToString(results[6]);
calc.CorporationId = 19;
_context.Calculations.AddOrUpdate(calc);
await SaveChangesAsync();
}
}
catch (Exception ex)
{
Logger.Error(ex);
}
return results;
}
有人有什么建议吗? 蒂亚。
更新:
请注意,我发现我缺少这个构造函数。
public MyModelUserRepository()
{
}
但是现在当我与邮递员检查时,我收到"500 内部服务器错误",所以有人有任何建议吗?
更新 2:
请注意,我已经构建了一个单元测试,它没有错误地通过,所以我不确定为什么邮递员请求失败。 有什么建议吗? 蒂亚。
[TestMethod]
public async Task GetMyModelCalculationAsync()
{
// Arrange
ICalcRepository calcRepository = new CalcRepository(_calcContext);
string username = "corpname";
string password = "licensekey";
double latitude = 12.3456;
double longitude = 198.76543;
double depth = 876;
// Act
var actual = await calcRepository.GetCalculationAsync(username, password, latitude, longitude, depth);
// Assert
Assert.AreEqual(Math.Round(24.5667789, 2), Math.Round(actual[0], 2));
Assert.AreEqual(Math.Round(87.3028596, 2), Math.Round(actual[1], 2));
}
错误消息的有趣部分是
在类型
EddiTools.Data.CalcRepository
上找到的带有Autofac.Core.Activators.Reflection.DefaultConstructorFinder
的构造函数都不能使用可用的服务和参数调用:无法解析构造函数
Void .ctor(EddiTools.Data.ICalcContext)
的参数EddiTools.Data.ICalcContext context
。
这意味着 Autofac 尝试创建CalcRepository
但没有可用的ICalcContext
。
如果您查看您的注册,则只注册类型而不指示它是ICalcContext
bldr.RegisterType<CalcContext>()
.InstancePerRequest();
如果将其更改为
bldr.RegisterType<CalcContext>()
.As<ICalcContext>()
.InstancePerRequest();
您的CalcContext
类型将被注册为ICalcContext
,这将使Autofac创建您的CalcRepository