使用无svc服务

时间:2015-05-01 17:38:03

标签: c# wcf autofac

我正在尝试将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,我不再在此代码中点击任何断点,表明它现在已被完全绕过。

3 个答案:

答案 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使用的名称匹配