Lets say I have 3 assemblies, Example.Core, Example.Contracts, Example.WcfServices. In my contracts assembly I define an interface and add some operation, e.g. ICalculator, which has operation Add(double a, double b). In my WcfServices assembly I have an implementation of ICalculator explosed as a Wcf service.
Now my question is this....in my Example.Core assembly how do I program against that interface while keeping everything decoupled (to allow me to have an alternative implementation of the interface). If I have a class that needs an ICalculator I can create one from say a ChannelFactory and use it, or I can inject an instance in the constructor. If I create one in the class then I am putting dependencies in my class on ChannelFactory/Wcf and I really don't want to do that. If I inject an instance in my constructor then how will the injecting class manage and tidy up the wcf service? It seems that although I have an interface I have no clean way of using it. I have looked at something like NInject, but I am not convinced that it would clean up the ChannelFactory if it faults (at least I haven't found any documentation that shows it knows when to call Abort rather than Close on the channel).
What I have ended up doing is implmenting my interface again and using the method described in this question: creating WCF ChannelFactory<T> and just recalling the methods on the service. This "smells" a bit to me as I am wrapping all my calls again just to ensure the channel is properly closed/aborted.
Has anyone any patterns/methods that cleanly have two implmentations of an interface, one of which is a Wcf service?
Thanks,
Mike.
I have used a variation of the answer linked in Mark's comment and this article here to come up with a solution that has worked for me.
Given the service contract you defined, step 1 will be to define an interface implementing your service and
IClientChannel
.Step 2 involves creating reusable code that will handle creating the proxies and implementing the code to close or abort connections.
The T in
ServiceClient<T>
will take theICalculatorChannel
defined in step 1. The ProxyGenerator is part of the Castle project. Its usage here is to allow us to intercept the calls to the WCF service and perform pre and post actions.As you can see, the Intercept method encapsulates the channel and the call to close the channel. The
closeChannel
method will handle the decision to callClose()
orAbort()
.Now we create a class to wrap up the usage of this ServiceClient.
Notice that the implementation of add no longer has to deal with the WCF connection concerns. The consuming class only has to know about the Service Contract. The ugliness of of dealing with faulted connections is now taken care of for us by the
ServiceClient
class.The client need only take on one dependency now.
And IOC can populate the client: