1

我拼命想让这个工作。我之前使用 WCF 服务用 JQuery 做 AJAX,没有任何麻烦。

现在我正在使用 Autofac 进行 DI,到目前为止它进展顺利,直到我希望我的 UI 项目中的 WCF 服务成为 AJAX 的基础。在我的常规 Web 应用程序中,我使用 Global.asax 'Application_Start' 来注册我的容器。这是通过在我的“MyBootstrapper”项目中调用 Boot() 方法来完成的。Boot() 方法只是注册了我所有的模块。

现在我注意到有一个 WCF 服务并通过使用“启用 AJAX 的 WCF 服务”模板,一旦调用该服务就不会调用 Global.asax。

为此,我制作了一个简单的 MyServiceHostFactory,其中包含一个 void host_Opening 方法,该方法在我的 Bootstrapper 中调用我的 Boot() 方法。这似乎进展顺利。虽然什么都没有设置。

这是我的 WCF 代码:

    [ServiceContract(Namespace = "MyWebApp.UI.Ajax")]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class MyAsyncService
    {
        public IPersonProvider PersonManager { get; set; }

        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
        public List<Person> GetPersons()
        {
            var persons = PersonManager.GetPersons();
            return persons;
        }
    }

MyAsyncService 的标记

<%@ ServiceHost Language="C#" Debug="true" Service="MyWebApp.UI.Ajax.MyAsyncService" CodeBehind="MyAsyncService.svc.cs" Factory="MyWebApp.UI.Ajax.MyAsyncServiceHostFactory"%>

MyAsyncServiceHostFactory:

public class MyAsyncServiceHostFactory : ServiceHostFactory, IContainerProviderAccessor
    {
        static IContainerProvider _containerProvider;

        public IContainerProvider ContainerProvider
        {
            get { return _containerProvider; }
        }

        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            var host = base.CreateServiceHost(serviceType, baseAddresses);
            host.Opening += host_Opening;
            return host;
        }

        void host_Opening(object sender, EventArgs e)
        {
            // Setup Autofac stuff.
            var container = MyBootLoader.Boot();
            _containerProvider = new ContainerProvider(container);
        }
    }

和 MyBootLoader:

 public static class MyBootLoader
    {
        public static IContainer Boot()
        {
            var builder = ConfigureContainer();
            return builder.Build();
        }

        private static ContainerBuilder ConfigureContainer()
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<PersonManager>().As<IPersonProvider>().InstancePerHttpRequest();
            return builder;
        }
    }

我的 web.config:

  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="MyWebApp.UI.Ajax.MyAsyncServiceAspNetAjaxBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
    <services>
      <service name="MyWebApp.UI.Ajax.MyAsyncService">
        <endpoint address="" behaviorConfiguration="MyWebApp.UI.Ajax.MyAsyncServiceAspNetAjaxBehavior"
          binding="webHttpBinding" contract="MyWebApp.UI.Ajax.MyAsyncService" />
      </service>
    </services>
  </system.serviceModel>

请问我错过了什么?一切似乎都通过了,但我的 PersonManager 在 MyAsyncService 中为 NULL。

4

2 回答 2

1

您是否按照 wiki 上有关 IIS 托管服务的说明进行操作?

https://code.google.com/p/autofac/wiki/WcfIntegration#IIS_Hosted_Services

您通常在其中配置容器并使用新建的容器Application_Start设置属性。AutofacHostFactory.Container然后将 .svc 文件中的工厂设置为AutofacWebServiceHostFactory. 如果您出于某种原因需要自定义工厂,您应该从现有的 Autofac 工厂实现之一派生。这些将行为添加到负责依赖注入的端点。

于 2013-05-13T13:03:32.850 回答
0

我让我的朋友帮助我,解决方案是将我的 *.svc 文件保留在我的 web.ui 项目中,并将代码隐藏文件保留在另一个 UI.Services 项目中。

在我的 *.svc 文件的标记文件中添加了以下内容:

<%@ ServiceHost Language="C#" Debug="true" Service="MyWebApp.UI.Services.MyAsyncService, MyWebApp.UI.Services"  Factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf" %>

这防止了循环引用问题,但增加了新程序集的成本。

在我的引导加载程序中,我添加了以下内容:

public static class MyBootLoader
{
    public static IContainer Boot()
    {
        var builder = ConfigureContainer();
        var container = builder.Build();

        AutofacHostFactory.Container = container;

        return container;
    }
    private static ContainerBuilder ConfigureContainer()
    {
        var builder = new ContainerBuilder();
        builder.RegisterType<PersonManager>().As<IPersonProvider>().InstancePerHttpRequest();
        return builder;
    }
}
于 2013-05-15T16:18:31.583 回答