T4 template that takes a DLL, pulls out all the WCF interfaces and gives your client development team a proxy class to code against.
namespace ServerInterfaces
{
[ServiceContract]
public interface ILoginFacade
{
[OperationContract]
[WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
Method = "GET", UriTemplate = "/Login")]
GetLoginResponse GetLogin()
[OperationContract]
[WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
Method = "PUT", UriTemplate = "/Login")]
UpdateLoginResponse UpdateLogin(UpdateLoginRequest request);
[OperationContract]
[WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
Method = "GET", UriTemplate = "/Login/WriteToLog")]
void WriteToLog();
}
[ServiceContract]
public interface ITradeFacade
{
[OperationContract]
[WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
Method = "PUT", UriTemplate = "/Trades")]
int UpdateTradesDatabase(string userId);
}
}
Generated Client Proxy
/***************************************************************************************
**** GENERATED CODE: Use t4toolbox & tangiblet4editor to update AsyncInterfaces.tt ****
****************************************************************************************/
using System;
using Newtonsoft.Json;
namespace WcfServiceDirectory
{
public partial class Services
{
public Services()
{
this.LoginFacade = new LoginFacade();
this.TradeFacade = new TradeFacade();
}
public LoginFacade LoginFacade { get; set; }
public TradeFacade TradeFacade { get; set; }
}
public class LoginFacade
{
private IServiceExecutor serviceExecutor;
public LoginFacade() { this.serviceExecutor = new ServiceExecutor(); }
public void GetLogin(Action<CallCompleteEventArgs<DTOs.GetLoginResponse>> callback)
{
serviceExecutor.Get<DTOs.GetLoginResponse>("/Login", callback);
}
public void UpdateLogin(DTOs.UpdateLoginRequest request, Action<CallCompleteEventArgs<DTOs.UpdateLoginResponse>> callback)
{
serviceExecutor.Put<DTOs.UpdateLoginResponse>("/Login", JsonConvert.SerializeObject(request), callback);
}
public void WriteToLog(Action<CallCompleteEventArgs<Object>> callback)
{
serviceExecutor.Get<Object>("/Login/WriteToLog", callback);
}
}
public class TradeFacade
{
private IServiceExecutor serviceExecutor;
public TradeFacade() { this.serviceExecutor = new ServiceExecutor(); }
public void UpdateTradesDatabase(System.String userId, Action<CallCompleteEventArgs<System.Int32>> callback)
{
serviceExecutor.Put<System.Int32>("/Trades", JsonConvert.SerializeObject(userId), callback);
}
}
}
Core REST service execution code
namespace ClientProxy
{
public interface IServiceExecutor
{
void Get<TResponse>(string uriTemplate, Action<CallCompleteEventArgs<TResponse>> callback);
void Put<TResponse>(string uriTemplate, string request, Action<CallCompleteEventArgs<TResponse>> callback);
}
public class ServiceExecutor : IServiceExecutor
{
ServiceEnvironment serviceEnvironment = new ServiceEnvironment() { UseHttpS = false, BaseAddress = "localhost", Port = 52802 };
public void Get<TResponse>(string uriTemplate, Action<CallCompleteEventArgs<TResponse>> callback)
{
var client = new WebClient();
var address = GetUri(uriTemplate);
client.DownloadStringCompleted += (sender, eventArgs) =>
{
if (callback == null) return;
var response = JsonConvert.DeserializeObject<TResponse>(eventArgs.Result);
callback(new CallCompleteEventArgs<TResponse>(response, eventArgs));
};
client.DownloadStringAsync(address);
}
public void Put<TResponse>(string uriTemplate, string request, Action<CallCompleteEventArgs<TResponse>> callback)
{
var client = new WebClient();
var address = GetUri(uriTemplate);
client.UploadStringCompleted += (sender, eventArgs) =>
{
if (callback == null) return;
var response = JsonConvert.DeserializeObject<TResponse>(eventArgs.Result);
callback(new CallCompleteEventArgs<TResponse>(response, eventArgs));
};
client.Headers[HttpRequestHeader.ContentType] = "application/json";
client.UploadStringAsync(address, "PUT", request);
}
private Uri GetUri(string uriTemplate)
{
var uriString = string.Format("http{0}://{1}:{2}/Facades{3}",
serviceEnvironment.UseHttpS ? "s" : "",
serviceEnvironment.BaseAddress,
serviceEnvironment.Port,
uriTemplate);
return new Uri(uriString);
}
}
}
Source code
The solution features:
- DTOS: A portable class library project containing DTOs
- Interfaces: A class library containing the WCF interfaces. This project also contains the T4 template scripts
- WCF ServiceDirectory: A Silverlight project which calls the rest services , contains REST service calling code.
- A website project with Web API (WCF) REST Services
https://github.com/stevenh77/AsyncServiceInterfaces