"确保控制器具有无参数的公共构造函数错误"部署之后

时间:2017-10-10 09:40:56

标签: c# .net asp.net-web-api dependency-injection asp.net-web-api2

只是为了给出一个快速背景:

  • 它在本地工作,但不是通过TeamCity和Octopus部署到服务器(Windows Server 2002)时
  • 我已经提取了TC生成的nuget packge并在本地发布,并且工作正常
  • 过去几天我搜索了很多内容
  • 尝试了很多解决方案
  • 我在特定的AppPool下部署了Api
  • 我的本地计算机是Windows 10

我有一个web api应用程序,在.net框架4.6上编码,并在我的一个控制器上使用Unity进行了一些依赖注入。 我正在Register方法中注册WebApiConfig上的依赖项,如下所示:

public static void Register(HttpConfiguration config)
{
        // Web API configuration and services
        var container = new UnityContainer();

        var logger = new LoggerFactory().CreateLogger();
        container.RegisterInstance(logger);

        container.RegisterType<IEventStoreConnection>(new InjectionFactory(c => PaymentRegistry.CreateEventStoreConnection(logger)));

        container.RegisterType<IAggregateRepository, AggregateRepository>(new HierarchicalLifetimeManager());
        container.RegisterType<IPaymentRepository, PaymentRepository>(new HierarchicalLifetimeManager());
        container.RegisterType<ICertificateRepository, CertificateRepository>(new HierarchicalLifetimeManager());
        container.RegisterType<ISaxoCallMetadataRepository, SaxoCallMetadataRepository>(new HierarchicalLifetimeManager());

        container.RegisterType<ISaxoCallMetadataService, SaxoCallMetadataService>(new HierarchicalLifetimeManager());
        container.RegisterType<ISaxoConvert, SaxoConvert>(new HierarchicalLifetimeManager());
        container.RegisterType<IPackageService, PackageService>(new HierarchicalLifetimeManager());
        container.RegisterType<ISaxoValidationStageOneService, SaxoValidationStageOneResponseService>(new HierarchicalLifetimeManager());
        container.RegisterType<ISaxoValidationStageTwoService, SaxoValidationStageTwoResponseService>(new HierarchicalLifetimeManager());
        container.RegisterType<ISaxoValidationService, SaxoValidationService>(new HierarchicalLifetimeManager());
        container.RegisterType<ISaxoEndOfDayResponseService, SaxoEndOfDayResponseService>(new HierarchicalLifetimeManager());
        container.RegisterType<ISaxoService, SaxoService>(new HierarchicalLifetimeManager());

        container.RegisterType<IAggregateRoot, PaymentAggregate>(new HierarchicalLifetimeManager());
        container.RegisterType<IExceptionLogger, SerilogExceptionLogger>(new HierarchicalLifetimeManager());
        container.RegisterType<IAuthenticationService, AuthenticationService>();

        // Web API routes
        config.DependencyResolver = new UnityResolver(container);
        config.MapHttpAttributeRoutes();

        config.Filters.Add(new GlobalExceptionFilterAttribute());
        config.Filters.Add(new AuthorizeAttribute());
        config.Filters.Add(new ApiKeyAuthenticationFilter(container.Resolve<IAuthenticationService>()));

        config.Services.Add(typeof(IExceptionLogger), container.Resolve<IExceptionLogger>());

        config.Formatters.Remove(config.Formatters.XmlFormatter);
        config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "{controller}/{action}/{batchPaymentId}",
            defaults: new { batchPaymentId = RouteParameter.Optional }
        );
 }

当我向Postman提出请求时,我得到了那个着名的确保控制器有一个无参数的公共构造函数错误:

{
    "message": "An error has occurred.",
    "exceptionMessage": "An error occurred when trying to create a controller of type 'SaxoPaymentController'. 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)\r\n   at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()",
    "innerException": {
        "message": "An error has occurred.",
        "exceptionMessage": "Type 'Payments.SaxoIntegration.Api.Controllers.SaxoPaymentController' does not have a default constructor",
        "exceptionType": "System.ArgumentException",
        "stackTrace": "   at System.Linq.Expressions.Expression.New(Type type)\r\n   at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)\r\n   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"
    }
}

任何人都知道如何修复它? 如果您需要进一步的详细信息,请与我们联系。

1 个答案:

答案 0 :(得分:0)

所以这里只是针对同一问题的更新。 我已经修复了以下两行的替换:

container.RegisterType<IEventStoreConnection>(new InjectionFactory(c => PaymentRegistry.CreateEventStoreConnection(logger)));

container.RegisterType<IAggregateRepository, AggregateRepository>(new HierarchicalLifetimeManager());

这个:

container.RegisterType<IAggregateRepository, AggregateRepository>(new HierarchicalLifetimeManager(), new InjectionConstructor(PaymentRegistry.CreateEventStoreConnection(logger)));

AggregateRepository 类有一个构造函数获取 IEventStoreConnection 作为参数,所以这里的重点是用替换 InjectionFactory 实现InjectionConstructor