Creating dynamic proxy using WCF ChannelFactory

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

What is WCF ChannelFactory

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

Difference between ChannelFactory and Proxy

Proxy ChannelFactory

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

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

Simple to use as you get the required configuration through the proxy.

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

You can create a WCF service proxy using WSDL or by adding a 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 restrictions

  1. Properties need to have getter and setter, you can not have read only or write only properties.
  2. You can not exposed class constructors.
  3. Only ServiceContract can be exposed, 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 a proxy by Visual Studio or SvcUtil.exe tool will update the 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 scenarios, services need to be tightly coupled and need to share not only ServiceContract but also other dependant methods, contracts etc. When you do not want to force clients 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 a dynamic proxy

Dynamically creating WCF Proxy using ChannelFactory

Create Shared WCF Contracts

As described in the 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 that uses ChannelFactory objects to call WCF Services.

Open NorthwindDynamicProxy solution which is created in the 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 a shared assembly, we have a CategoryService contract which we will implement using ChannelFactory.

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

CategoryService has two method

1. GetCategoryName which returns category name based on the given category ID. Below is the 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 the first step. In this step we create a declartive endpoint to CategoryServiceHost.

ChannelFactory<ICategoryService> creates a 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 call CategoryService with dynamic proxy and returns the 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 the Category data contract and will test dependent clients. Open the 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 the existing implementation. Now run your client code without changing anything. Client code should give you the same output shown previously. As Proxy is created 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

Source code on Git hub Source Code on Github

Speak your mind
Please login to post your comment!


Blog Search





If you like my content please feel free to buy me coffee. Buy Me A Coffee