Channel factory in Wcf

https://philmunro.wordpress.com/2012/02/15/creating-a-wcf-service-proxy-with-channelfactory/

Creating a WCF service proxy with ChannelFactory<T>

Before going into the details of using ChannelFactory, if you are not familiar with service proxies (or have used them but don’t understand why they’re important) here’s a little bit of background. When a client application makes a call to a service, it shouldn’t know or care  about the implementation details or physical location of the service. All the client should be aware of is that there is an object which provides some useful functionality. Everything else about the service should be hidden away.
And this is exactly what a proxy does – it hides the technical details of the service from the client by adding an extra layer in between. The proxy object exists in the same memory address space as the client and marshals calls across to the service on the client’s behalf. The service could be a WCF service with TCP bindings which is hosted somewhere on the same local area network as the client, or it could be a RESTful HTTP service hosted in the cloud on the other side of the world. It simply doesn’t matter. All the client needs to know are the details of the proxy. The service which sits behind the proxy is effectively invisible.
This is good software design and ensures your clients and services remain loosely coupled and are therefore easier to maintain. If there are any physical changes to a service (e.g. a newer version becomes available which just happens to be implemented in a different technology) it is the proxy that will change, not the client. With any luck, you shouldn’t have to touch the client code at all. However avoiding changes to the client is less easy if the interface to an existing service changes. I describe how to minimise the impact of changes to service contracts on the client in more detail here.
ChannelFactory<T>
Using the ChannelFactory<T> class to make calls to your WCF services is an easier alternative to the laborious process of generating proxies via the SvcUtil tool every time a service contract changes. As its name suggests, ChannelFactory is a factory for creating service communication channels at runtime. This means no matter how often your service contracts change, you won’t have to manually re-generate proxy classes or alter client-side service model config each time.
ChannelFactory<T> takes a generic parameter of the service type you want to create a channel for (this must be the contract interface). And as an absolute minimum, it requires a specific binding and endpoint address. You can supply additional information, but this is enough to achieve a remote connection to the service.
Because ChannelFactory only requires knowledge of the service contract, it makes good design sense to put your service/data contracts and service implementations in separate assemblies (never put your service contracts and service implementation in the same assembly). This way, you can safely distribute contract assemblies to third parties who wish to consume your services, without the risk of disclosing their actual implementation.
Example usage
As an example, here’s a very basic service contract. To keep things simple, I haven’t used any data contract parameters but if there were any, the data contract type declarations should be included with the service contract interfaces in the same contract assembly. This is so that you can share the contract assembly with other solutions or distribute to third parties (otherwise clients won’t be able to instantiate the parameter types).

Here is the service implementation.

And here is the client-side code to call the service using ChannelFactory<T>.

As you can see it’s surprisingly simple. It doesn’t look like much but we are still supplying the essential ABC requirements of WCF. A is the address of the service endpoint, B is the binding (in this case I’ve used basic HTTP binding because that is the default service binding – client and service bindings must always match), and C is the contract interface. You don’t need any more than this to achieve a service connection. At this point you are probably wondering why you’ve spent so much time messing around with complicated client-side WCF config!
A reusable proxy base class
But as I explained earlier, you don’t want this sort of infrastructure code dotted throughout your client applications. It should be wrapped in a service proxy class. You also don’t want boilerplate service code duplicated over and over again in different proxy classes, so here is a generic base class to take care of the specific details of creating a channel. If you don’t already have one, create a WCF infrastructure assembly and add the proxy base class to it for future reuse with different solutions.

Notice that the base class is thread-safe – a crucial but sometimes overlooked issue with server-side classes. Also notice for the sake of clarity, I omitted the region which implements IDisposable which is shown below:

You could also extend the base class constructor to take different bindings, etc, but I’ll leave that down to you. Now to see this in action, all you need is a concrete proxy class which is strongly typed to your service contract:

Notice that the proxy class name is the name of the service but with a ‘Client’ suffix. This is a standard WCF naming convention which you should follow so that other developers will immediately understand its purpose.  Also notice how the GetMessage method is simply a wrapper for a call to the GetMessage operation exposed by the service contract, but the client has no knowledge of this. All it knows is that it calls a local method and gets a return value.
Wrapping it all up
Finally, put the concrete proxy class in its own service proxy assembly (don’t be tempted to just add it directly to a client project). Having the abstract base and concrete proxy classes in separate assemblies will promote reuse with different client applications and across different solutions meaning you and other developers will be able to use these assemblies straight out of the box when they need to communicate with the same service.
And here is the revised client code which now calls the service via the proxy:

See how simple this has become compared to the original client code earlier which called ChannelFactory<T> directly?  I have included a service endpoint URL in this example but even that would be hidden away in a config file in a real application, so the client really is achieving quite a lot through some very minimal code.  This will keep your client code clean and simple, speed up development time in the future and reduce maintenance costs.
Also see the follow-up post how to avoid changing WCF service contracts which describes good contract design.




Introduction

In this article I will show you the difference betweens a WCF Channel factory and Proxy and when to use a Proxy and when to use a Channel Factory.

Background

There are three ways to create a WCF client:
  • Proxy
  • WCF Channel Factory
  • REST services, using HttpClient or WebClient

Using the code

Before going into the differences, I will explain what a WCF channel factory is and what a proxy is in WCF and when to use a Proxy and when to use a channel factory.

What is Proxy

Proxy is a CLR class that exposes a single CLR interface representing the service contract.
A proxy is the same as a service contract, but also has additional methods for managing the proxy life cycle and the connection to the service. The proxy gives the following details: its location, its implementation technology, and run time platform and communication transport.
A proxy can be generated in two ways:
  1. By using Visual Studio: by right clicking References and clicking on Add Service Reference. Then open the Add Service Reference dialog box where you have to specify the base address of the service and the namespace that contains the proxy.
  2. This auto generates proxy code that connects to the service by reading the WSDL (Web Service Descriptive language). If the service address changes for any reason you have to regenerate it. The big advantage of this is that it is easy to set up - Visual Studio has a wizard and it's all automatic. The disadvantage is that you're relying on Visual Studio to do all the hard work for you, and so you lose control.
  3. Using the SvcUtil.exe command-line utility. We have to provide SvcUtil with the HTTP-GET address or the metadata exchange endpoint address and, optionally, using svcutil.exe, it creates a proxy that derives from System.ServiceModel.ClientBase<TChannel>.

2. What is Channel Factory

Use the ChannelFactory class with a known interface. This depends on you having local interfaces that describe the service contract. The big advantage is that you can change more easily. But you still have to recompile and fix changes, but now you're not regenerating code, you're only referencing the new interfaces. Channel factory is commonly used when you have control of both the server and the client.
In ChannelFactory<T> you must share contract assemblies between the service and the client. That's why ChannelFactory<T> can save you time.
When your project shares a common service contract DLL between the client and the server, you have to use the ChannelFactory class.
For using channel factory, the following steps are necessary:
  1. Create a binding in WCF
  2. Create a ChannelFactory class
  3. Create a Channel
  4. Send-Receive messages over that channel
Example:
In the below example, we use the ChannelFactory class and we send messages back and forth to the service.
using System;
using System.ServiceModel;
using ClientConsole.ServiceReference;

namespace ClientConsole
{
    internal class Program
    {
        private static void Main()
        {
            var channelFactory =
                new ChannelFactory<IEchoService>(
                    "WSHttpBinding_IService" // endpoint name
                    ); 

            IService channel = channelFactory.CreateChannel();
            Message result = channel.Echo(
                new Message
                    {
                        Text = "Hey "  
                    });

            Console.WriteLine("Service given respond at {0}: {1}",
                              result.Invoked,
                              result.Text);
            Console.ReadLine();

            ((IClientChannel)channel).Close();
        }
    }
}

Difference between proxy and channel factory

ProxyChannel Factory
1Only requires a URL where the service residesYou must have direct access to the assembly that contains the service contract
2Very simpleNot easier
3Easy to understandChannels are complex, network-related
4Visual Studio gives you the Add the Reference optionWhen you share a common service contract DLL between the client and the server, you'll be using the ChannelFactory class
5Proxies have several restrictions like:
  1. Properties need to have gets and sets
  2. Constructors can't be exposed
  3. Methods other than the service contract cannot be exposed
If you know that your entities will not change much and the client code is less, then a DLL would work better than a proxy
6By using SVCutil.exe, you can create a proxyWhen you are using a DLL that refers to the service contract interface then use the channel factory class


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

Comments