Creating dynamic proxy using WCF ChannelFactory

This article helps you to generate dynamic wcf service proxy using ChannelFactory. This will also describes what is ChannelFactory, difference between ChannelFactory and Proxy, and when to use proxy or ChannelFactory.


What is WCF ChannelFactory

ChannelFactory enables you to dynamically creating a proxy object based on the Service Contract alone. You do not require to explicitly generating a proxy class or manually define. This is helpful in scenario where your service address changes frequently or DataContract changes to newer version and as a client you have lot of references to those services. So after changes happens at service side, client must update proxy.


Difference between ChannelFactory and Proxy

Proxy ChannelFactory

You need service URL and metadata endpoint should be exposed from service side.

You have to have direct access to ServiceContracts, DataContracts, MessageContracts.

Simple to use as you get required configuration through proxy.

Comparing with Proxy, creatin ChannelFactory is complex as you need to configure at code level.

You can create WCF service proxy using WSDL or by adding Service Reference in Visual Studio Solution explorer

You can create ChannelFactory by adding reference to assembly where required ServiceContract, DataContract, MessageContracts resides.

Proxy has below restrications

  1. Properties needs to have getter and setter, you can not have read only or write only properties.
  2. You can not expose class constructors.
  3. Only ServiceContract can be expose, you can not expose any other method than ServiceContracts OperationContract.

ChannelFactory has below restrictions

  1. It requires direct access to the ServiceContracts, DataContracts and any other dependent methods.

When to use Proxy?

Creating proxy by Visual Studio or SvcUtil.exe tool will update client configuration file to make necessary changes. If you know your services are generic enough and services should be loosely coupled you should use Proxy. As it depends on Service schema, any changes to existing service schema force client to rebuild.


When to use ChannelFactory

In some scenario services needs to be tightly coupled and needs to share not only ServiceContract but also other dependant methods, contracts etc. When you do not want to force client to change or rebuild on frequent service schema, you have to share utility methods, different internal services, contracts along with ServiceContract then you should use ChannelFactory.

Below details explains about how to use ChannelFactory to create dynamic proxy


Dynamically creating WCF Proxy using ChannelFactory


Create Shared WCF Contracts

described in introduction, for using ChannelFactory you need to have access to ServiceContract and related DataContract.

Go through Share WCF Service Contracts assembly which helps you to create a shared library which includes ServiceConracts and DataContracts which can be shared by WCF Services and its clients.


WCF Client with ChannelFactory

In this step we will create a WCF client which uses ChannelFactory objects to call WCF Services.

Open NorthwindDynamicProxy solution which is created in previous step. Add New Console Application to solution by right click on solution NorthwindDynamicProxy -> New Project -> Console Application. Name it as NorthwindClient and click Ok.

Now Add Reference to NorthwindContracts assembly to NorthwindClient console application so that you will be able to access required contracts.


CategoryServiceClient

In shared assembly we have CategoryService contract which we will implement using ChannelFactory.

Add new class to NorthwindClient console application and name it as CategoryServiceClient.

CategoryService has two method

1. GetCategoryName which returns category name based on given category ID. Below is implementation of this GetCategoryName.

                                
public static string GetCategoryName(int categoryID)
{
    string categoryName = string.Empty;
    WSHttpBinding myBinding = new WSHttpBinding();
    EndpointAddress myEndpoint = new 
        EndpointAddress("http://localhost:7741/CategoryServiceHost.svc");
    ChannelFactory<ICategoryService> myChannelFactory = 
                new ChannelFactory<ICategoryService>(myBinding, myEndpoint);

    ICategoryService instance = myChannelFactory.CreateChannel();
            
    categoryName = instance.GetCategoryName(categoryID);

    myChannelFactory.Close();

    return categoryName;
}
            

2. GetCategoryDetails which returns category details as Category DataContract. Below is GetCategoryDetails of this method.

                
public static Category GetCategoryDetails(int categoryID)
{
    Category category = new Category();

    WSHttpBinding myBinding = new WSHttpBinding();
    EndpointAddress myEndpoint = new 
        EndpointAddress("http://localhost:7741/CategoryServiceHost.svc");
    ChannelFactory<ICategoryService> myChannelFactory 
            = new ChannelFactory<ICategoryService>(myBinding, myEndpoint);

    ICategoryService instance = myChannelFactory.CreateChannel();

    category = instance.GetCategoryDetails(categoryID);                  

    myChannelFactory.Close();

    return category;
}
            

We assume that you have created a WCF service and hosted in IIS as suggested in first step. In this step we create a declartive endpoint to CategoryServiceHost.

ChannelFactory<ICategoryService> creates new instance of CategoryService and ChannelFactory.CreateChannel() returns instance using which we can call service operations dynamically.


Call to dynamic service proxy class

Open Program.cs file of NorthwindClient console application. From Program.cs file we will call CategoryServiceClient's methods which calls CategoryService with dynamic proxy and returns output.

Add below code to Program.cs

                
    using NorthwindContracts.DataContracts;   
    using NorthwindContracts.ServiceContracts;   

    namespace NorthwindClient
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine(CategoryServiceClient.GetCategoryName(10));

                Category category = 
                        CategoryServiceClient.GetCategoryDetails(10);
                if (category != null)
                {
                    Console.WriteLine("Category ID " + category.CategoryID);
                    Console.WriteLine("Category Name: " 
                             + category.CategoryName);
                    Console.WriteLine("Category Description:"
                             + category.CategoryDescription);                    
                }

                Console.Read();             
            }
        }
    } 
            

Change existing WCF contracts

In this step we will change Category data contract and will test dependent clients. Open NorthwindContracts class library project. Open Category DataContract from DataContract folder.

Add below new DataMember.

                
[DataMember]
public string CategoryURL { get; set; }
                    
            

Now open NorthwindServices WCF Service Library project and CategoryService from CategoryServices folder.

Change implementation of GetCategoryDetails method as

                
public Category GetCategoryDetails(int categoryID)
{
    Category category = new Category();
    category.CategoryID = 1;
    category.CategoryName = "Beverages";
    category.CategoryDescription = 
            "Soft drinks, coffees, teas, beers, and ales";
    category.CategoryURL = "http://northwind.com/Beverages"; 

    return category;
}        
            

Notice that we have added CategoryURL in addition to existing implementation. Now run your client code without changing anything. Client code should give you same output shown previously. As Proxy is crated dynamically you do not need to make any changes or rebuild to client code.

Now change client code from Program.cs to display CategoryURL as

                
Category category = CategoryServiceClient.GetCategoryDetails(10);
if (category != null)
{
    Console.WriteLine("Category ID " + category.CategoryID);
    Console.WriteLine("Category Name: " + category.CategoryName);
    Console.WriteLine("Category Description:" + 
                        category.CategoryDescription);
    Console.WriteLine("Category URL: " + category.CategoryURL); 
}
    

Notice that we did not change anything to CategoryServiceClient which actually creates ChannelFactory and dynamic proxy to services.

wcf proxy using ChannelFactory

Download source code.

Speak your mind :
Leave a comment for this article on dotnetbloogers.com