Introduction
In conventional method, if client proxy for a WCF service is required to be
generated at runtime programmatically, an instance of ChannelFactory (generic
type) is created passing the interface type of the service (contract) as
parameter to the generic class. This requires different implementation for
different services for generating client proxy which reduces the generic
scope.
This article describes a method to create a factory class which generates
client proxy at runtime from the type of the service contract received as
parameter. This will eliminate separate implementation requirement by using a
single factory class with the help of .NET reflection. |
Background
For
example, we have the following Service and Service Contract for a WCF
service:
[ServiceContract()]
interface IMyService
{
[OperationContract()]
void DoSomething();
}
public class MyService : IMyService
{
public void DoSomething()
{
}
}
Conventional
Method of Client Proxy Generation at Runtime
To
generate client proxy in conventional method is to create the
ChannelFactory
with a prior knowledge of Service contract and this
will require separate implementation for each service in the
system:
public class Test
{
public void Test()
{
BasicHttpBinding myBinding = new BasicHttpBinding();
EndpointAddress myEndpoint = new EndpointAddress("http://localhost/MyService/");
ChannelFactory<imyservice> myChannelFactory = new ChannelFactory<imyservice>(myBinding, myEndpoint);
IMyService pClient = myChannelFactory.CreateChannel();
pClient.DoSomething();
((IClientChannel)pClient).Close();
}
}
Factory
Method of Client Proxy Generation at Runtime
The following
method will eliminate the above deficiency by providing a client
factory class. This will help in generating client proxy in a more
generic way using the single factory:
public class Test
{
public void Test()
{
IMyService pClient = (IMyService)ClientFactory.CreateClient(typeof(IMyService));
pClient.DoSomething();
((IClientChannel)pClient).Close();
}
}
public abstract class ClientFactory
{
public static object CreateClient(Type targetType)
{
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress addess = new EndpointAddress(GetAddessFromConfig(targetType));
object factory = Activator.CreateInstance(typeof
(ChannelFactory<>).MakeGenericType(targetType), binding, address);
MethodInfo createFactory = factory.GetType().GetMethod("CreateChannel", new Type[] { });
return createFactory.Invoke(factory, null);
}
}