14

我在使用 Autofac 1.4.5 将服务依赖项注入我的 WCF 服务时遇到问题。我已经阅读并关注了WcfIntegration 上的 Autofac wiki 页面,但我的调试显示我的 WCF 服务是由该System.ServiceModel.Dispatcher.InstanceBehavior.GetInstance()方法创建的,而不是由AutofacWebServiceHostFactory. 我究竟做错了什么?

我已将我的ajax.svc文件设置为与示例中的文件类似,以用于WebHttpBinding

<%@ ServiceHost Language="C#" Debug="true"
    Service="Generic.Frontend.Web.Ajax, Generic.Frontend.Web"
    Factory="Autofac.Integration.Wcf.AutofacWebServiceHostFactory,
             Autofac.Integration.Wcf" %>

我的 WCF 服务类Ajax是这样定义的:

namespace Generic.Frontend.Web
{
    [ServiceContract]
    [AspNetCompatibilityRequirements(
        RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Ajax
    {
        public MapWebService MapWebService { get; set;}

        public Ajax() {
            // this constructor is being called
        }

        public Ajax(MapWebService mapWebService)
        {
            // this constructor should be called
            MapWebService = mapWebService;
        }

        [WebGet(ResponseFormat = WebMessageFormat.Json)]
        [OperationContract(Name = "mapchange")]
        public MapChangeResult ProcessMapChange(string args)
        {
            // use the injected service here
            var result = MapWebService.ProcessMapChange(args);
            return result;
        }
    }
}

现在我已经使用了Global.asax.cs上面提到的 wiki 中所示的接线:

var builder = new ContainerBuilder();
builder.RegisterModule(new AutofacModuleWebservice());
var container = builder.Build();
AutofacServiceHostFactory.Container = container;

class AutofacModuleWebservice : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.Register<Ajax>();
        builder.Register<MapWebService>().ContainerScoped();
    }
}

在我的 web.config 我有

<services>
    <service name="Generic.Frontend.Web.Ajax">
        <endpoint address="http://mysite.com/ajax.svc/" binding="webHttpBinding"
                  contract="Generic.Frontend.Web.Ajax" />
    </service>
</services>

.

该服务已经正常工作,但我无法让 Autofac 位(阅读:创建/注入)工作。有任何想法吗?

编辑: 不幸的是,删除默认构造函数会导致以下异常:

System.InvalidOperationException:
The service type provided could not be loaded as a service because it does not
have a default (parameter-less) constructor. To fix the problem, add a default
constructor to the type, or pass an instance of the type to the host.

干杯,奥利弗

4

5 回答 5

1

您的服务设置是否使用 InstanceContextMode.Single?如果是,那么 wcf 将使用默认构造函数创建您的服务。要解决这个问题,请更改您的实例上下文模式并让 autofac 管理您的服务的生命周期。

于 2010-08-16T19:35:36.543 回答
0

我刚刚得到了相同的 System.InvalidOperationException 并通过将实现的 ServiceBehavior InstanceContextMode 从 InstanceContextMode.PerCall 更改为 InstanceContextMode.PerSession 来解决它,也许您的 AutoFac 生命周期范围与您的 Web 服务实现不同步?

对于测试 AutoFac 服务创建,我建议创建一个单元测试并直接解决它们,因为这将突出显示任何问题并提供更有意义的异常消息。对于具有请求生命周期范围的服务,创建一个测试 aspx 页面并再次直接解析它们。

于 2010-12-15T12:51:21.973 回答
0

尝试删除默认Ajax构造函数并将构造函数修改为此。如果它运行mapWebService == null,则表明存在分辨率问题。

    public Ajax(MapWebService mapWebService = null)
    {
        // this constructor should be called
        MapWebService = mapWebService;
    }
于 2010-07-29T01:25:45.960 回答
0

我遇到了同样的问题,在寻找答案时遇到了这个问题。

就我而言,使用属性注入有效,并且问题中的代码已经具有可以使用的属性:

namespace Generic.Frontend.Web
{
    [ServiceContract]
    [AspNetCompatibilityRequirements(
        RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Ajax
    {
        // inject the dependency here
        public MapWebService MapWebService { get; set;}

        [WebGet(ResponseFormat = WebMessageFormat.Json)]
        [OperationContract(Name = "mapchange")]
        public MapChangeResult ProcessMapChange(string args)
        {
            // use the injected service here
            var result = MapWebService.ProcessMapChange(args);
            return result;
        }
    }
}

并注册以使用属性注入(来自 wiki 的示例代码和语法已更改,因为现在使用的是 2.5.2.830 版本):

builder.RegisterType<Ajax>().PropertiesAutowired();
于 2011-09-21T20:32:26.400 回答
0

按照说明为我解决了它:

code.google.com/p/autofac/wiki/... 我只是这样做:builder.RegisterType();

我已经按照他们的指示更改了 .svc 文件。

当你查看你的 .svc 文件时,你没有得到任何关于那里出错的提示吗?

您通过 iis 托管它并且不使用 WAS,我没有看到您用于覆盖 global.asax.cs 的代码

将全局文件添加到您的解决方案中并在那里实现:

  protected void Application_Start(object sender, EventArgs e)
        {
            // build and set container in application start
            IContainer container = AutofacContainerBuilder.BuildContainer();
            AutofacHostFactory.Container = container;


        }

AutofacContainerBuilder 是我的容器构建器。

于 2013-10-04T08:26:43.797 回答