我在使用Autofac 1.4.5将服务依赖项注入我的WCF服务时遇到问题。我已阅读并关注Autofac wiki page on WcfIntegration,但我的调试显示我的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.
干杯,奥利弗
答案 0 :(得分:1)
您的服务是否使用InstanceContextMode.Single进行设置?如果是,那么wcf将使用默认构造函数创建您的服务。要解决此问题,请更改实例上下文模式,并让autofac管理服务的生命周期。
答案 1 :(得分:0)
尝试删除默认的Ajax
构造函数并修改构造函数。如果它与mapWebService == null
一起运行,则表示解决问题。
public Ajax(MapWebService mapWebService = null)
{
// this constructor should be called
MapWebService = mapWebService;
}
答案 2 :(得分:0)
我刚刚获得相同的System.InvalidOperationException并通过将实现的ServiceBehavior InstanceContextMode从InstanceContextMode.PerCall更改为InstanceContextMode.PerSession来解决它,可能您的AutoFac生命周期范围与您的Web服务实现不同步?
为了测试AutoFac服务创建,我建议创建一个单元测试并直接解析它们,因为这会突出显示任何问题并提供更有意义的异常消息。对于具有请求生存期范围的服务,请创建一个测试aspx页面并再次直接解析它们。
答案 3 :(得分: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();
答案 4 :(得分: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是我的容器构建器。