Wednesday, June 2, 2010

Consume WCF Service Without creating Proxy ( Use of ChannelFactory Class)

In the old classic way, we used to refer the services using “Add Service reference” to the application and use the services. There are so many de-merits with this approach. One of them is, once we change the definition of the service, we have to update the service in the client layer.

To avoid this, we can use the ChannelFactory class. But how to use this class? Following sample may help us on this.

1. Create a Service Project WCFProxyService
2. Move the service Interface IService (ServiceContract) to another project, For this add a class library project called WCFContrcat and move the ServiceContract
3. Add Reference to the following assemblies
a. System.Runtime.Serialization
b. System.ServiceModel
4. Let us see the ServiceContract and DataContract code in this Interface

using System.Runtime.Serialization;
using System.ServiceModel;


// NOTE: If you change the interface name "IService" here, you must also update the reference to "IService" in Web.config.
[ServiceContract]
public interface IService
{

[OperationContract]
string GetData(int value);

[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);

// TODO: Add your service operations here
}

// Use a data contract as illustrated in the sample below to add composite types to service operations.
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";

[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}

[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}


5. The implementation of the Service class will be as below

// NOTE: If you change the class name "Service" here, you must also update the reference to "Service" in Web.config and in the associated .svc file.
public class Service : IService
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}

public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}

6. Create the Client Project “WCFProxy” and refer the “WCFContract” project to this project.
7. Modify the App.config file, Configuration section as below



8. Now add a new class “ProxyHelper.cs” to the Client Project “WCFProxy”
Use of this class is to create the Proxy on the fly.
9. Following is the code will help us to create the proxy on the fly using ChannelFactory class

using System.ServiceModel;

namespace WCFProxy
{
public class ProxyHelper
{
IService channel = null;
ChannelFactory factory = null;

public ProxyHelper()
{
factory = new ChannelFactory("WSHttpBinding_IService");
channel = factory.CreateChannel();
}

public string GetData()
{
string value = channel.GetData(1);
factory.Close();
return value;
}

public CompositeType GetDataUsingDataContract(CompositeType cType)
{
CompositeType returnType = channel.GetDataUsingDataContract(cType);
factory.Close();
return returnType;
}


}
}


10. Add reference to the same two Assemblies as specified in step 3
11. Please check the above code, how the ChannelFactory is used to call the service methods
12. Using the Helper class we can call the service methods

Usally this helper class will be used as the Proxy class, that dynamically create the proxy at Runtime. Below is the code shows the way Helper class is being used.

ProxyHelper pHelper=new ProxyHelper();
MessageBox.Show(pHelper.GetData());

CompositeType cType = new CompositeType();
cType.BoolValue = true;

cType.StringValue = "Arun ";

pHelper = new ProxyHelper();
cType = pHelper.GetDataUsingDataContract(cType);

MessageBox.Show(cType.StringValue);

Hope the above will help and will improve the maintainability of your application.