【问题标题】:How to inject WCF Service Implementation into another WCF Service with Autofac如何使用 Autofac 将 WCF 服务实现注入另一个 WCF 服务
【发布时间】:2019-06-15 22:29:31
【问题描述】:

我在 IIS 中托管了多个 WCF 服务并使用 Autofac 进行了配置。

Global.asax

var builder = new ContainerBuilder();

builder.RegisterType<ServiceA>();
builder.RegisterType<ServiceB>();
builder.RegisterType<ServiceC>();

var container = builder.Build();
AutofacHostFactory.Container = container;

web.config

<system.serviceModel>
  ...
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
    <serviceActivations>
      <add service="ServiceA, MyServicesAssembly" relativeAddress="./ServiceA.svc" factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf" />
      <add service="ServiceB, MyServicesAssembly" relativeAddress="./ServiceB.svc" factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf" />
      <add service="ServiceC, MyServicesAssembly" relativeAddress="./ServiceC.svc" factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf" />
    </serviceActivations>
  </serviceHostingEnvironment>
<system.serviceModel>

服务实现

public class ServiceA : IServiceA 
{
    public ServiceA()
    {            
    }
}

public class ServiceB : IServiceB
{
    public ServiceB()
    {            
    }
}

public class ServiceC : IServiceC
{
    public ServiceC(IServiceA serviceA)
    {            
    }
}

如您所见,ServiceC 与其他不同,需要实现 IServiceA。 Autofac 无法解决,因为没有注册 IServiceA。

所以我把注册改成这样:

builder.RegisterType<ServiceA>().As<IServiceA>();

Autofac 现在可以成功解析 ServiceC,但 WCF 托管不再工作:

在 mscorlib.dll 中出现“System.ServiceModel.ServiceActivationException”类型的异常,但未在用户代码中处理

所以我的问题是:

有没有一种方法可以让我同时拥有一个托管的 WCF 服务实例,以及将服务实现传递给另一个服务的可能性?全部配置了 AutoFac? 我也在考虑一种解决方法,但我想到的每件事都需要付出巨大的努力。 我知道这些服务需要重构,这样就不需要传入另一个“服务”。但这是另一回事。

【问题讨论】:

  • 如果您遵循 SOA/微服务的一些最佳实践,那么您希望将服务层从业务逻辑中分离出来,后者与 WCF 完全无关(另一个 .dll)留下WCF 层通过facade pattern 成为一个薄包装器。考虑到这一点,不是将ServiceA 的WCF 实例注入ServiceC,而是注入ServiceCBusiness(可能继承IServiceAImpl)。然后每当ServiceC 调用IServiceA 时,它不会越过WCF 层(可能还有网络层),从而提高性能
  • ....但话又说回来,我从不喜欢注入业务层的想法,因为它们通常是static。你可以在这里阅读更多关于 SOA 模式的信息patterns.arcitura.com/soa-patterns/design_patterns/…
  • @MickyD 是的,对于真正的微服务而言,注入一个服务或另一个服务的业务逻辑都是错误的。这里的服务都在同一个进程中运行,没有什么是真正解耦的。还有很多事情要做......但现在我只是在寻找一个快速的解决方案。

标签: c# wcf dependency-injection autofac


【解决方案1】:

如果您想将组件公开为一组服务以及 使用默认服务,使用AsSelf方法:

//...

builder.RegisterType<ServiceA>()
    .AsSelf() //<--
    .As<IServiceA>();

//...

这会将类和接口关联在一起,以便可以根据需要注入IServiceA,并将其解析为ServiceA。这也允许 WCF 在注册 ServiceA 时不会中断。

参考Autofac Documentation: Registration Concepts

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 2018-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    相关资源
    最近更新 更多