There are three most commonly used ways to consume a WCF Service in a Service Oriented
Application built on the WCF Infrastructure which are as follows:
a) Referencing WCF Service from VS.NET Studio 2010.
b) Executing ServiceModel Metadata Utility Tool (Svcutil.exe) and retrieve metadata
from a WCF service and use it to create a WCF proxy that can access the service.
c) Using ChannelFactory<TContract> class used in advanced scenarios that can
be used to create more than one channel(to create multiple endpoint listeners).
There are other approaches which are more advanced and less common to all. One such
approach is generating proxy using the Mex service endpoints at runtime and another,
worth mentioning is using the discovery API. No matter what approach is being
used, the code block must always be executed the Dispose method so that it improves
performance and releases memory right away (however, the GC still decides when
to collect it).
Problem with invoking the Dispose method is due to the fact that there is no such
design restriction in place which ensures the Dispose method always executes.
Today, if you invoke Dispose method, you invoke it. If you don’t, you don’t.
Well, you know your requirement and you got to execute it at any cost.
So, this ProxyInvoker class is designed to fill this gap using the power of lambda
expression, Execute Around Method pattern and ChannelFactory<TContract>
class. Well, there is another approach which is not so clean but it works is
using .NET reflection. But this approach much either in a way that you need to
specify the method name as string parameter and passing arguments as object[]
value. On the other hand, this ProxyInvoker class is really a cool design which
does exactly the same thing but works with type safety and performs better. It
is a static class which provides two set of public methods that you can use to
execute your WCF Service methods. It guarantees that the Dispose method is always
executed and the Execute<> methods are all you have it.
First set of methods are defined to configure through configuration file from the
serviceModel section:
object Execute<TContract> (string name, Func<TContract, object> invoker)
object Execute<TContract, THeader> (string name, THeader header, Func<TContract,
object> invoker)
Second set of methods are defined to use explicitly the binding and address objects
without a configuration file:
object Execute<TContract> (Binding binding, EndpointAddress address, Func<TContract,
object> invoker)
object Execute<TContract, THeader> (Binding binding, EndpointAddress address,
THeader header, Func<TContract, object> invoker)
Either case you need to write a code block that matches to Func delegate. And that’s
where you are executing your type safe WCF methods.
The following code snippet shows the examples:
ProxyInvoker.Execute<IHelloService> (configName, (proxy) => { return proxy.Eecho(“Hello, World!”); }); ProxyInvoker.Execute<IHelloService>(binding,
address, (proxy) => { return proxy.Eecho(“Hello, World!”); });
Finally, this is how the Execute<> method makes sure that dispose is invoked
always:
try
{
if (header == null)
{
return invoker.Invoke((TContract)proxy);
}
using (OperationContextScope ocs = new OperationContextScope((proxy as IContextChannel)))
{
OperationContext.Current.OutgoingMessageHeaders.Add( MessageHeader.CreateHeader(headerName, headerNamespace, header)); return invoker.Invoke((TContract)proxy);
}
}
finally
{
if (proxy != null) { proxy.Dispose(); }
}