• ServiceActivationException when auto-starting WCF services with AutofacServiceHostFactory


    ServiceActivationException when auto-starting WCF services with AutofacServiceHostFactory

     I switched teams at work and as a welcome gift into the new team I got to investigate the following error:

    Exception: System.ServiceModel.ServiceActivationException: The service '/AuthorisationService.svc' cannot be activated due to an exception during compilation. The exception message is: The AutofacServiceHost.Container static property must be set before services can be instantiated.. —> System.InvalidOperationException: The AutofacServiceHost.Container static property must be set before services can be instantiated. at Autofac.Integration.Wcf.AutofacHostFactory.CreateServiceHost(String constructorString, Uri[] baseAddresses) at System.ServiceModel.ServiceHostingEnvironment.HostingManager.CreateService(String normalizedVirtualPath, EventTraceActivity eventTraceActivity) at System.ServiceModel.ServiceHostingEnvironment.HostingManager.ActivateService(ServiceActivationInfo serviceActivationInfo, EventTraceActivity eventTraceActivity) at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity) — End of inner exception stack trace — at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity) at System.ServiceModel.ServiceHostingEnvironment.EnsureServiceAvailableFast(String relativeVirtualPath, EventTraceActivity eventTraceActivity) Process Name: w3wp Process ID: 9776

    The troublesome service is hosted in an ASP.NET web application and it's preloaded with a custom implementation of IProcessHostPreloadClient which more or less does what's described in this blog post. Since the project hosting the service is using AutoFac as it's DI framework/library the service is setup to use AutofacServiceHostFactory as the service factory: 

    <%@ ServiceHost
      Service="AuthorizationServiceImpl, AuthorizationService"
      Factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf" %>

     After some googling for the error I turned out to the AutoFac documentation page where I got the first idea of what is happening:

    When hosting WCF Services in WAS (Windows Activation Service), you are not given an opportunity to build your container in the ApplicationStart event defined in your Global.asax because WAS doesn’t use the standard ASP.NET pipeline.

     Ok, great! Now I know that ServiceHostingEnvironment.EnsureServiceAvailable() method (which is called to activate the service) doesn't use the HTTP pipeline from ASP.NET. A solution to this issue is in the next paragraph of the documentation:

    The alternative approach is to place a code file in your App_Code folder that contains a type with a public static void AppInitialize() method.

    And that's what I did. I went to to the project in Visual Studio, added a special ASP.NET folder named App_Code and added a class named AppStart to it with a single method public static void AppInitialize() which contained all the required bootstrapping logic for AutoFac. I redeployed the application on but the error kept popping and it's after carefully reading the comments from this StackOverflow answer and this blog post on how to initialize WCF services I found why the AppInitialize method wasn't invoked: it was because the AppStart.cs needs it's build action to be Content not Compile

     So when getting the ServiceActivationexception with the error message The AutofacServiceHost.Container static property must be set before services can be instantiated make sure to have the following:

    1. The special ASP.NET folder App_Code
    2. A class in App_Code having a method with this signature public static void AppInitialize() which contains all the required initialization code
    3. The build action of the file containing the above method is set to Content as shown in the picture below 

    How to Initialize Hosted WCF Services

    Using AppInitialize

    The above global.asax does not work for non-HTTP protocols such as net.tcp and net.pipe that is supported by the Windows Activation Service (WAS) on Windows Vista. There is no protocol-agnostic counterpart for HttpApplication in this case.

    Fortunately, ASP.NET provides a simple hook that works in a protocol agnostic way. The hook is based on the following AppInitialize method:

        public static void AppInitialize();

    This method can be put in any type that is defined in a C# file in the application’s App_Code directory. When the AppDomain is started, ASP.NET checks whether there is a type that has such as method (exact name and signature) and invokes it. Note that the AppInitialize method can be only defined once and it has to be in a code file instead of a pre-compiled assembly.

  • 相关阅读:
    dapperHelper
    .NET Core Session的使用方法
    Wpf 关闭当前窗体 打开新窗体
    C#中Split分隔字符串的应用(C#、split、分隔、字符串)
    wpf日期控件
    SQLite数据库数据类型详解
    Asp.Net Core 2.2
    手写图片懒加载
    css动画常用属性总结
    css购物车(抛物线)运动
  • 原文地址:https://www.cnblogs.com/chucklu/p/14371983.html
Copyright © 2020-2023  润新知