我刚刚阅读了a fantastic article有关WCF事务和流程的信息。几乎只留下了一个悬而未决的问题:
我有一个单个项目,定义了两个服务方法:
ServiceA.svc
[OperationBehavior(TransactionScopeRequired = true)]
OperationA()
ServiceB.svc
[OperationBehavior(TransactionScopeRequired = true)]
OperationB()
OperationA()
需要致电OperationB()
。
我可以很容易地在new ServiceB().OperationB(...)
内说出ServiceA
(记得我说他们在同一服务器上运行的同一个网络项目中。
起初我认为这就是我要做的事情,但我不确定交易是否会全部搞砸 - 特别是如果两个业务之间的交易合同不同。显然,如果我从Transaction.Current
内访问OperationB
,那么它将存在,但如果这两个操作有不同的合同(如参考文章中所述),则不会遵循规则。
ServiceA.OperationA()
拨打ServiceB.OperationB()
的正确方法是什么?
(好奇当一个操作在同一个类中调用另一个操作时如何执行此操作,但这可能是google更容易的事情)
答案 0 :(得分:1)
WCF的基本假设是始终通过客户端代理调用服务方法。此行为允许WCF运行时进入调用堆栈并完成其所有魔法。
因此,在您的情况下,如果要从ServiceA调用ServiceB,则应在ServiceA内为ServiceB创建客户端代理,并在该客户端代理上调用ServiceBClientProxy.OperationB()
。
您可以通过多种方式创建客户端代理:
通过Visual Studio“添加服务引用”对话框,该对话框基本上只调用svcutil.exe
命令行实用程序,您也可以直接调用它。这创造了很好的代理和所有但可怕的配置
由于这两项服务属于同一个项目,两者都可以访问彼此的合同,对吧?在这种情况下,您可以在几行代码中手动创建客户端代理。
基本上,您需要的是ServiceB服务合同的ChannelFactory<T>
实例,然后在该通道工厂上调用CreateChannel()
方法以获取该实际通道(=客户端代理)服务。像这样:
ChannelFactory<IServiceB> factory = new ChannelFactory<IServiceB>();
IServiceB clientProxy = factory.CreateChannel();
这将获取web.config中的所有详细信息 - 如果需要,可以在代码中定义绑定和端点,并将它们传递给ChannelFactory的构造函数。
现在您拥有ServiceB的客户端代理,您可以调用其所有方法。这是在WCF中这样做的正确方法。
希望这有点帮助!