views:

144

answers:

1

I just read a fantastic article about WCF transactions and flow. Pretty much only left me with one unanswered question:

I have a single project with two service methods defined:

ServiceA.svc

   [OperationBehavior(TransactionScopeRequired = true)]
   OperationA()


ServiceB.svc

  [OperationBehavior(TransactionScopeRequired = true)]
  OperationB()

OperationA() needs to call OperationB().

I could quite easily just say new ServiceB().OperationB(...) from within ServiceA (remember i said they are in the same web project running on the same server.

At first I thought this is what I would do, but I'm not sure if transactions will all get screwed up or not - especially if the transaction contracts differed between the two operations. Obviously if I'm accessing Transaction.Current from within OperationB then it will exist, but if the two operations had diffrent contracts (as described in the referenced article) the rules would not be followed.

What's the correct way for ServiceA.OperationA() to call ServiceB.OperationB()?

(Curious also how to do this when one operation calls another in the same class, but thats probably an easier thing to google for)

+1  A: 

The basic assumption with WCF is that you always call a service method through a client proxy. This behavior allows the WCF runtime to get into the call stack and do all its magic.

So in your case, if you want to call ServiceB from ServiceA, you should create a client proxy for ServiceB inside ServiceA and call ServiceBClientProxy.OperationB() on that client proxy.

You can create a client proxy in several ways:

  • through the Visual Studio "Add Service Reference" dialog, which under the covers just basically calls the svcutil.exe command line utility, which you can also call directly. This creates nice proxies and all, but horrible configs

  • since these two services are in the same project, both will have access to each other's contracts, right? In that case, you can manually create a client proxy in a few lines of code.

Basically, what you need is a ChannelFactory<T> instance for your ServiceB's service contract, and then you call the CreateChannel() method on that channel factory to get the actual channel (= the client proxy) for that service. Something like this:

 ChannelFactory<IServiceB> factory = new ChannelFactory<IServiceB>();
 IServiceB clientProxy = factory.CreateChannel();

This takes all the details from the web.config - if you want, you could define bindings and endpoints in code and pass them into the constructor for the ChannelFactory.

Now you have a client proxy for ServiceB and you can call all its methods. That's the proper way of doing it in WCF.

Hope this helps a bit!

marc_s
thats what i was looking for thanks. i have a WCF book on my kindle but its pain to find stuff like this. ps. i'm up from 30% from last time you mentioned it :-)
Simon_Weaver