This project is read-only.

WCF AutoMagic

WCF is flexible and powerful. And as usual this flexibility comes at the price of complexity. Creating the correct configuration for a service and then matching that configuration on the client side is a tedious and error-prone task. WCF 4.0 introduced a new feature called WCF Discovery, which promises configuration-less clients for WCF services. Combined with Unity this feature allows for seamless integration of WCF with the rest of your application.

Setup the host for discovery.
ServiceHost host = new ServiceHost(typeof(SyncService), Constants.BaseAddress);
host.AddServiceEndpoint(typeof(ISyncService), new NetTcpBinding(SecurityMode.None), string.Empty);
host.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
host.AddServiceEndpoint(new UdpDiscoveryEndpoint());
Tell Unity what type of service it should resolve using discovery.
var container = new UnityContainer();
container.AddNewExtension<WcfProxyContainerExtension>();
container.RegisterType<ISyncService>(new AutoDiscoveryProxyFactory());
Resolve and call the service.
var service = container.Resolve<ISyncService>();
var response = service.DoWork("input");
Done.

But it does not stop there. Service calls take time. That's why they are often called asynchronously. The problem is: implementing an asynchronous service isn't an easy task. The good thing is: You don't have to do it!

WCF does that for you and Unity can completely hide that effort from you.

You declare a synchronous service contract like the one below and implement it.

[ServiceContract]
public interface ISyncService
{
  [OperationContract]
  string DoWork(string input);
}
And on the client side you define an asynchronous contract.

[ServiceContract(Name = "ISyncService")]
public interface IAsyncService
{
  [OperationContract(AsyncPattern = true)]
  IAsyncResult BeginDoWork(string input, AsyncCallback callback, object userState);
  string EndDoWork(IAsyncResult result);
}
Now you tell Unity to build you a proxy for the asynchronous contract.

var container.RegisterType<IAsyncService>(new AutoDiscoveryProxyFactory());
var service = container.Resolve<IAsyncService>();
And finally you can call the synchronous service in an asynchronous manner.
var result = service.BeginDoWork(
	"input",
	asyncResult =>
		{
			var resultFromService = service.EndDoWork(asyncResult);
			// work with result
		},
	0);
See the full code in TecX.ServiceModel.Unity and the according test project.

Last edited Feb 13, 2012 at 12:32 PM by weberse, version 8

Comments

No comments yet.