using System; using System.Collections.Generic; using System.Text; using System.ServiceModel; using System.ServiceModel.Dispatcher; using System.ServiceModel.Description; using System.ServiceModel.Channels; using System.Xml; namespace WCFMiddleTier { [ServiceContract] public interface IService { [OperationContract] Message Increment(Message input); } [ServiceBehavior(IncludeExceptionDetailInFaults=true, InstanceContextMode=InstanceContextMode.Single)] public class MyService : IService { #region IService Members public Message Increment(Message input) { //Dummy implementations return null; } #endregion } class Program { static void Main(string[] args) { try { string address = "http://localhost:8080/MyService"; ServiceHost host = new ServiceHost(new MyService(), new Uri[] { new Uri(address) }); ServiceEndpoint sep = host.AddServiceEndpoint(typeof(IService), new BasicHttpBinding(), ""); foreach (OperationDescription od in sep.Contract.Operations) { od.Behaviors.Add(new MyOperationBehavior()); } host.Open(); //Wait for client to connect } catch (Exception e) { Console.WriteLine(e); } Console.ReadLine(); } } public class MyMessageFormatter : IDispatchMessageFormatter { #region IDispatchMessageFormatter Members public void DeserializeRequest(Message message, object[] parameters) { //Transform message to required SOAP format //Copy the transformed SOAP as parameter parameters[0] = transformed_message; } public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result) { //result is backend reply so convert it to a WCF reply Message //return the transformed message return transformed_result; } #endregion } public class MyOperationInvoker : IOperationInvoker { #region IOperationInvoker Members public object[] AllocateInputs() { //Always assume there is going to be only one input parameter return new object[1]; } public object Invoke(object instance, object[] inputs, out object[] outputs) { //Retrieve BackendMessage from the input array BackendMessage request = inputs[0] as BackendMessage; //Invoke Backend logic BackendReply reply = DoBackEndWork(BackendMessage); //Create memory for 0 output parameter outputs = new object[0]; //return backendreply return BackendReply; } public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state) { //Not implementing Async throw new Exception("The method or operation is not implemented."); } public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result) { throw new Exception("The method or operation is not implemented."); } public bool IsSynchronous { //For sample reason, async is not implemented get { return true; } } #endregion } //Use this to plug in your custom IDispatchMessageFormatter and IOperationInvoker. public class MyOperationBehavior : IOperationBehavior { #region IOperationBehavior Members public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { //Noop } public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { //Noop } public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation) { dispatchOperation.Formatter = new MyMessageFormatter(); dispatchOperation.Invoker = new MyOperationInvoker(); } public void Validate(OperationDescription operationDescription) { //Noop } #endregion } }