Autofac and ASP .Net Web API version 4.2.0 .NET Framework 4.



请注意,我使用的是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

最新更新