【问题标题】:Dependency Injection with WCF proxy使用 WCF 代理进行依赖注入
【发布时间】:2010-11-22 09:26:23
【问题描述】:

我有一个使用另一个服务 (Service2) 的服务 (Service1)。我正在为这两个服务使用依赖注入,并且需要将 Service2 的代理注入到 Service1 中。

我不确定如何处理代理不是 IService2 类型的简单类而是继承自 ClientBase 的代理这一事实。显然,我的 Service1 实现需要打开代理,并且还应该在使用后关闭它,或者如果发生异常则中止它,但是如果我只是注入 IService2 的一个实例,那么我不能这样做(没有强制转换),因为 Open、Close 和 Abort 方法在基类上,而我的操作在接口上。

在测试 Service1 时,我希望只模拟接口,但如果 Service1 实现需要 Open、Close 和 Abort 方法,那么这很棘手。过去,我做过类似这样的骇人听闻的事情,但一定有更好的方法!

var proxyBase = _service2 as ClientBase;

if (proxyBase != null)
{
  proxyBase.Open();
}

_service2.DoOperation("blah"); //the actual operation

if (proxyBase != null)
{
  proxyBase.Close();
}

// repeat for Abort in exception handler(s).

其他人在做什么?

谢谢

【问题讨论】:

    标签: wcf dependency-injection proxy mocking ioc-container


    【解决方案1】:

    为 WCF 服务添加服务引用而获得的自动生成的类被实现为分部类。我所做的是为该类创建另一个部分文件并实现一个公开这些方法的接口,然后在通常使用 ClientBase 或 WCF 接口的地方使用该接口

    public partial class Service2 : IClientService2  
    {}
    

    如果 IClientService2 具有与 ClientBase 方法匹配的 Abort 和 Close 方法,那么它应该是您所需要的。

    public interface IClientService2 : IService2 // where IService2 is the WCF service interface
    {
        void Abort();
        void Close();
    }
    

    我建议注入工厂来构建 WCF 服务,而不是注入代理本身,因为当发生故障时,通道将不再能够使用,您将需要构建新的代理。

    IClientService2 proxy = _service2Factory.Create();
    
    
    proxy.Open();
    
    
    proxy.DoOperation("blah"); //the actual operation
    
    
    proxy.Close();
    

    【讨论】:

    • 我使用相同的解决方案,除了我的 IClientService2 接口继承自 ICommunicationObject 而不是具有 Abort & Close 方法。 (当然它也继承自 IService2)。
    【解决方案2】:

    由于 Wcf 的要求,您的界面受到污染。如果您不使用 wcf,您将没有 Open and Close 方法。在理想情况下,界面应该看起来与服务正在处理中一样。

    您是否选择了您的 IoC 容器?如果您还没有,我会考虑查看Windsor。这将允许您维护一个干净的接口,并将服务作为进程中对象或 wcf 代理注入。

    container = new WindsorContainer().AddFacility<WcfFacility>();
    
    container.Register(Component
      .For<IClientService2>()
      .ActAs(DefaultClientModel)
      .On(WcfEndpoint.FromConfiguration("YourServiceNameInConfiguration")))
      .LifeStyle.Transient);
    

    WcfFacility将为您完成所有频道的打开和关闭。

    【讨论】:

    • 有趣。我以前在服务端使用过 Windsor WCF 项目,但对客户端的东西一无所知。不幸的是,我必须使用 Unity。
    • 我以前使用过 Unity,当时它还比较新,如果没有实现类似的东西,我会感到惊讶。
    【解决方案3】:

    我最终使用了this approach,它使用 Castle Dynamic Proxy 来拦截调用并处理 WCF 细节。它工作得非常好,并允许注入代理的类将其视为普通类/接口。然后通过模拟服务契约接口,这个类完全可以进行单元测试。

    【讨论】:

      猜你喜欢
      • 2011-04-24
      • 2011-03-01
      • 2015-09-13
      • 1970-01-01
      • 2015-09-26
      • 2014-01-19
      • 2014-03-25
      • 2019-11-21
      • 1970-01-01
      相关资源
      最近更新 更多