WCF和Castle Windsor - 看起来你忘记了

use*_*628 4 c# service wcf castle-windsor windsor-3.0

我们最近开始迁移到Castle Windsor,我在运行WCF服务时遇到了一些问题.它是IIS中的常规Windows服务,我们提供SSL材料并使用自定义X509CertificateValidator来验证客户端提供的证书.

下面是我用来创建WCF服务的代码.它位于引用它的WCF服务的单独项目中.

public IWindsorContainer RegisterService<T,K>(
            IServiceBehavior customBehavior, 
            Action<ServiceHost> onCreate = null,
            Action<ServiceHost> onOpen = null, 
            Action<ServiceHost> onClose = null, 
            Action<ServiceHost> onFault = null) where T : class where K : T
        {

            var facility = this.AddFacility<WcfFacility>(f => f.CloseTimeout = TimeSpan.Zero);

            var serviceModel = new DefaultServiceModel()
                .OnCreated(onCreate)
                .OnOpened(onOpen)
                .OnClosed(onClose)
                .OnFaulted(onFault);

            var service = Component.For<T>()
                    .ImplementedBy<K>()
                    .AsWcfService<T>(serviceModel)
                    .LifestylePerWcfOperation<T>();

            if (customBehavior != null)
                facility.Register(Component.For<IServiceBehavior>().Instance(customBehavior));

            facility.Register(service);

            return facility;

        }
Run Code Online (Sandbox Code Playgroud)

该服务按预期启动(我可以使用chrome导航到该服务而没有任何问题),并且该服务正在呈现并验证SSL材料(即命中自定义验证器)但在此之后,客户端获取此信息FaultException:

Looks like you forgot to register the http module Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule
To fix this add
<add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
to the <httpModules> section on your web.config.
If you plan running on IIS in Integrated Pipeline mode, you also need to add the module to the <modules> section under <system.webServer>.
Alternatively make sure you have Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 assembly in your GAC (it is installed by ASP.NET MVC3 or WebMatrix) and Windsor will be able to register the module automatically without having to add anything to the config file.
Run Code Online (Sandbox Code Playgroud)

下面是我的一大块,我App.Config试图将模块放在通过谷歌和一些猜测建议的所有区域:

...
<system.web>
    <httpModules>
      <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
    </httpModules>
    <membership defaultProvider="ClientAuthenticationMembershipProvider">
      <providers>
        <add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
      </providers>
    </membership>
    <roleManager defaultProvider="ClientRoleProvider" enabled="true">
      <providers>
        <add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
      </providers>
    </roleManager>
  </system.web>
  <system.webServer>
    <modules>
      <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
    </modules>
    <handlers>
      <add name="PerRequestLifestyle" verb="*" path="*.castle" preCondition="managedHandler" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Microkernel"/>
    </handlers>
  </system.webServer>
  <system.serviceModel>
    <extensions>
      <endpointExtensions>
        <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
      </endpointExtensions>
      <bindingExtensions>
        <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
      </bindingExtensions>
      <behaviorExtensions>
        <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
      </behaviorExtensions>
      <bindingElementExtensions>
        <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
      </bindingElementExtensions>
    </extensions>
...
Run Code Online (Sandbox Code Playgroud)

我几乎没有想法.有谁知道原因是什么?如果没有,任何人都可以解释更多关于我得到的错误?任何帮助将非常感激!

use*_*628 6

我再次回答我自己的问题(发布后的第二天,亲爱的):P

这个错误信息正在这里抛出(感谢上帝开源!):

https://github.com/castleproject/Windsor/blob/016730de012f15985410fb33e2eb907690fe5a28/src/Castle.Windsor/MicroKernel/Lifestyle/PerWebRequestLifestyleModule.cs

tldr - 见下文:

public class PerWebRequestLifestyleModule : IHttpModule
{
    ...
    private static void EnsureInitialized()
        {
            if (initialized)
            {
                return;
            }
            var message = new StringBuilder();
            message.AppendLine("Looks like you forgot to register the http module " + typeof(PerWebRequestLifestyleModule).FullName);
            message.AppendLine("To fix this add");
            message.AppendLine("<add name=\"PerRequestLifestyle\" type=\"Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor\" />");
            message.AppendLine("to the <httpModules> section on your web.config.");
            if (HttpRuntime.UsingIntegratedPipeline)
            {
                message.AppendLine(
                    "Windsor also detected you're running IIS in Integrated Pipeline mode. This means that you also need to add the module to the <modules> section under <system.webServer>.");
            }
            else
            {
                message.AppendLine(
                    "If you plan running on IIS in Integrated Pipeline mode, you also need to add the module to the <modules> section under <system.webServer>.");
            }
#if !DOTNET35
            message.AppendLine("Alternatively make sure you have " + PerWebRequestLifestyleModuleRegistration.MicrosoftWebInfrastructureDll +
                               " assembly in your GAC (it is installed by ASP.NET MVC3 or WebMatrix) and Windsor will be able to register the module automatically without having to add anything to the config file.");
#endif
            throw new ComponentResolutionException(message.ToString());
        }
    ...
}
Run Code Online (Sandbox Code Playgroud)

从这一点我很快收集到问题是PerWebRequestLifestyleModule没有被初始化,这对我来说没问题,因为我不需要它来提供这项服务!

进一步查看我自己的代码,我为这个服务加载的一些存储库设置为LifestylePerWebRequest在我们的Web控制台,宾果游戏中使用它们时使用!

将它们调整为其他东西(在本例中为'LifestylePerWcfOperation`)之后一切正常.