Click here to Skip to main content
15,886,026 members
Articles / WCF

Transparent WCF Channel Management with Unity

Rate me:
Please Sign up or sign in to vote.
4.64/5 (5 votes)
29 Aug 2009LGPL33 min read 25.9K   3   7
Transparent WCF Channel Management with Unity

Introduction

It is generally considered good form to define a separate ServiceContract interface for all WCF services. By doing so, it decouples the contract from the implementation. Still, if we consume a service contract via conventional means such as generating a proxy using a ChannelFactory or using a ServiceReference generated proxy, we couple the service with the WCF infrastructure. So what could be wrong with that? Well, say if we have a local version of a service, and a remote implementation of the service, one must be retrieved using a WCF specific measure like those just mentioned, while the other can be registered with our DI container and retrieved that way. But the code that is shared between the local and remote implementations must be aware of this, and this inhibits reusability. Wouldn’t it be better if retrieval of all services was done homogeneously? We can indeed achieve this, and without any coupling to the WCF infrastructure. I will explain how in just a moment, but first some background.

Background

I choose to manage my service channels in a centralized way. I do this by using an IChannelManager implementation. You can find out more about the use of the IChannelManager implementation in a number of my articles. In particular, here and here.

There are several advantages to this approach, not least of which is that the Channel Manager takes care of caching channel proxies, and recreating them if and when a fault occurs.

Using Unity’s IStaticFactoryConfiguration to Transparently Retrieve Proxies

Those familiar with Unity will know that to register a type or an instance with the container, one can either define the association in config or at runtime by calling the Containers RegisterInstance or RegisterType methods. There is, however, a third approach: we can register a factory method to perform the retrieval by configuring the IStaticFactoryConfiguration. This enables us to have Unity drive the generation or retrieval of a channel proxy using the ChannelManagerSingleton.

Figure: Retrieval of a service channel via Unity.

Firstly, we must register the extension with Unity. The extension can be found in the Microsoft.Practices.Unity.StaticFactory.dll assembly, and should be reference by your project. We then add the extension to our Unity container like so:

C#
Container.AddNewExtension<StaticFactoryExtension>();

We are then able to have Unity retrieve the IChannelManager instance in order to retrieve the service proxy when it is requested.

C#
var channelManager = UnitySingleton.Container.Resolve<IChannelManager>();
UnitySingleton.Container.Configure<IStaticFactoryConfiguration>().RegisterFactory<IMyService>(
				container => channelManager.GetChannel<IMyService>());

Thus, we no longer need to retrieve the IChannelManager in our code in order to retrieve the channel proxy. All we need do is grab it straight from Unity like so:

C#
var myService = UnitySingleton.Container.Resolve<IMyService>();

Opening the channel, testing connectivity, caching it, etc., is all done behind the scenes!

There is a drawback to this approach. If, for whatever reason, the channel proxy is unable to be retrieved by the Channel Manager, then Unity will raise a ResolutionFailedException, and the reason for the failure will be hidden as an inner exception. So, we must gear our code to be resilient to resolution failures and depend not only on Unit Tests discovering missing type registrations. This post covers simplex services, and I have still to explore an elegant way to achieve the same result for duplex services with their callback instances.

Conclusion

We have seen how, by using Unity, we are able to further abstract the retrieval of channel proxies. This allows us to consume services in the same way whether they be local or via WCF. By doing this, we are able to achieve location agnostic service consumption, and increase the reusability of shared code across local and remote deployment scenarios. The source for the Channel Manager and other goodies can be found here.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
Engineer
Switzerland Switzerland
Daniel is a former senior engineer in Technology and Research at the Office of the CTO at Microsoft, working on next generation systems.

Previously Daniel was a nine-time Microsoft MVP and co-founder of Outcoder, a Swiss software and consulting company.

Daniel is the author of Windows Phone 8 Unleashed and Windows Phone 7.5 Unleashed, both published by SAMS.

Daniel is the developer behind several acclaimed mobile apps including Surfy Browser for Android and Windows Phone. Daniel is the creator of a number of popular open-source projects, most notably Codon.

Would you like Daniel to bring value to your organisation? Please contact

Blog | Twitter


Xamarin Experts
Windows 10 Experts

Comments and Discussions

 
Generalclue on how to get location agnostic service [modified] Pin
terry7891-Sep-09 1:42
terry7891-Sep-09 1:42 
GeneralRe: clue on how to get location agnostic service Pin
Daniel Vaughan13-Dec-09 4:00
Daniel Vaughan13-Dec-09 4:00 
Generalsmall threading problem with ServiceContractBase Pin
the_bts31-Aug-09 15:03
the_bts31-Aug-09 15:03 
GeneralRe: small threading problem with ServiceContractBase Pin
Daniel Vaughan13-Dec-09 4:02
Daniel Vaughan13-Dec-09 4:02 
QuestionDisposal of th proxy? Pin
the_bts30-Aug-09 18:05
the_bts30-Aug-09 18:05 
AnswerRe: Disposal of th proxy? Pin
Daniel Vaughan31-Aug-09 10:29
Daniel Vaughan31-Aug-09 10:29 
GeneralRe: Disposal of th proxy? Pin
the_bts31-Aug-09 13:24
the_bts31-Aug-09 13:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.