Introduction
This tip discusses how to use DynamicProxy
to hide the fact that a WCF proxy is closed after each call and re-created.
Background
Creating a WPF application using MVVM we had code, like view models calling services, or actually being dependent on an interface which would then be a service proxy. I wanted to have the proxy closed after each call (which is another discussion), but I didn't want the user of the proxy to have any knowledge of ICommunicationObject
, because it would make testing harder and make things more complex. In general, I wanted to mock the service interface in my unit tests.
So I wanted to hide the fact that the implementation was in fact a service proxy and let the implementation handle the configuration, creation and closing of the channel.
Using the Code
The first thing I made was a small helper class, ProxyWrapper
, that would ensure proper closing of the proxy. If the service is faulted, Abort()
should be called, etc.
ProxyWrapper.Use(m_ChannelFactory.CreateChannel, proxy =>
{
proxy.ServiceMethod();
}
After that, I looked into dynamic proxy generation using Castle.Core DynamicProxy
. This came in handy, because I could dynamically create a class that implemented the ServiceContract
from where I could intercept each call to any method on the proxy. Intercept the method call, create the channel using a reusable ChannelFactory
, pass through the method arguments to the real instance of the proxy, and close the proxy after use.
This is how you create your reusable proxy instance.
var address = "net.tcp://localhost:5465/Service";
var serviceFactory = new ServiceFactory<IService>();
var proxy = serviceFactory.CreateChannel(address, new NetTcpBinding());
Other configuration method could easily be created as needed.
Points of Interest
Remember to always reuse a ProxyGenerator
class. For each ProxyGenerator
you get, a new assembly will be created. This could lead to a "memory leak".
The ServiceFactory
also hooks nice and easily into any IoC container. With Unity, you would use an InjectionFactory
.