我正在尝试将Autofac设置为我正在处理的新WCF项目的DI容器。我们正在使用无svc配置和自托管。如果没有Autofac,只使用穷人的DI,一切都按照预期的方式工作,但是当我将Autofac添加到混音中时,就会出现问题。
我用来设置所有内容的代码是:
public class CustomServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
var container = InitializeDIContainer();
var customHost = new CustomServiceHost(serviceType, baseAddresses);
// Exception is being thrown on the line below
customHost.AddDependencyInjectionBehavior(serviceType, container);
return customHost;
}
private static IContainer InitializeDIContainer()
{
var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(typeof (AccountRepository).Assembly)
.Where(t => t.Name.EndsWith("Repository"))
.As(t => t.GetInterfaces().FirstOrDefault(
i => i.Name == "I" + t.Name));
builder.RegisterAssemblyTypes(typeof (AccountService).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.As(t => t.GetInterfaces().FirstOrDefault(
i => i.Name == "I" + t.Name));
builder.RegisterType<tktktktkDbContext>().As<IDataContextAsync>();
builder.RegisterType<UnitOfWork>().As<IUnitOfWorkAsync>();
var container = builder.Build();
return container;
}
}
运行时,我收到以下异常:
An exception of type 'System.ArgumentException' occurred in Autofac.Integration.Wcf.dll but was not handled in user code.
Additional information: The service contract type 'tktktktk.Services.AccountClassService' has not been registered in the container.
当我在代码中放置一个断点并检查容器时,我可以看到我的所有服务,包括&t; tktktktk.Services.AccountClassService&#39;对象,在ComponentRegistry.Registrations集合中。
我已经尝试重新编写我的web.config文件以使用&#34; Autofac.Integration.Wcf.AutofacServiceHostFactory&#34;工厂,但是我的应用程序在它到达这一点之前就失败了。
我以为我错过了某个地方的一个步骤,但我不知所措。非常感谢任何帮助!
更新
我修改了我的web.config以使用&#34; Autofac.Integration.Wcf.AutofacServiceHostFactory&#34;如..所示。我现在收到以下错误:
WebHost failed to process a request.
Sender Information: System.ServiceModel.ServiceHostingEnvironment+HostingManager/45653674
Exception: System.ServiceModel.ServiceActivationException: The service '/Account/AccountClassService.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.
更新2
我尝试了下面答案中的建议,我得到了与上面相同的错误。我注意到的一件事是,当我将AutofacServiceHost.Container = container
添加到我的代码中时,无法编译。我把它切换到AutofacHostFactory.Container
并且编译得很好。此外,随着web.config更改为使用Autofac.Integration.Wcf.AutofacServiceHostFactory
,我不再在此代码中点击任何断点,表明它现在已被完全绕过。
答案 0 :(得分:1)
我也尝试过svc-less配置。我按照文档中的步骤操作并收到此错误消息:
The service 'MyService' configured for WCF is not registered with the Autofac container.
事实证明一切都已正确注册,但是&#34;添加工厂&#34; web.config中的元素需要服务的程序集名称,就像.svc文件存在一样:
<add factory="Autofac.Integration.Wcf.AutofacServiceHostFactory" relativeAddress="~/MyService.svc" service="NameSpace.Service, AssemblyName" />
Autofac documentation未提及此内容或在示例中显示此内容。此外,Visual Studio将抱怨并强调该属性,但服务将正确运行。
答案 1 :(得分:0)
以下是您使用自定义主机的情况,另一方面,Autofac将内置的ServiceHost作为开箱即用的功能提供。
您需要设置属性Container AutofacServiceHost
class:
public class CustomServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
var container = InitializeDIContainer();
// Add this line and try again.
AutofacServiceHost.Container = container;
var customHost = new CustomServiceHost(serviceType, baseAddresses);
customHost.AddDependencyInjectionBehavior(serviceType, container);
return customHost;
}
private static IContainer InitializeDIContainer()
{
var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(typeof (AccountRepository).Assembly)
.Where(t => t.Name.EndsWith("Repository"))
.As(t => t.GetInterfaces().FirstOrDefault(
i => i.Name == "I" + t.Name));
builder.RegisterAssemblyTypes(typeof (AccountService).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.As(t => t.GetInterfaces().FirstOrDefault(
i => i.Name == "I" + t.Name));
builder.RegisterType<tktktktkDbContext>().As<IDataContextAsync>();
builder.RegisterType<UnitOfWork>().As<IUnitOfWorkAsync>();
var container = builder.Build();
return container;
}
}
答案 2 :(得分:0)
我自己遇到了这个问题。我设法通过使用Named
样式注册
```
builder.RegisterType<YourServiceType>()
.Named<object>("myservice");
//and in your config:..
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" >
<serviceActivations>
<add relativeAddress="~/serviceurl.svc" service="myservice" factory="Autofac.Integration.Wcf.AutofacServiceHostFactory"/>
</serviceActivations>
</serviceHostingEnvironment>
```
请注意,在我的情况下,我没有使用apsnetcompatibilitymode。
我认为它是AutofacHostFactory中的一个错误,它使用错误的servicename标识符来解析wcfservice类型。
使用Named
注册样式,您基本上确保注册的类型和AutofacHostFactory使用的名称匹配