1 / 47

WCF Architecture and Extensibility P oints

CON 413. WCF Architecture and Extensibility P oints. Justin Smith Technical Evangelist http://blogs.msdn.com/justinjsmith. Agenda. Bindings Channel Managers Channels Messages XmlWriters and XmlReaders Message Encoders Dispatcher and Behaviors. WCF Architecture: Layers of Layers.

grady
Download Presentation

WCF Architecture and Extensibility P oints

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CON 413 WCF Architecture and Extensibility Points Justin Smith Technical Evangelist http://blogs.msdn.com/justinjsmith

  2. Agenda Bindings Channel Managers Channels Messages XmlWriters and XmlReaders Message Encoders Dispatcher and Behaviors

  3. WCF Architecture: Layers of Layers Sender Receiver Sender Application Receiver Application ServiceModel Layer Proxy Dispatcher Channels Channels Channel Layer

  4. Agenda Bindings Channel Managers Channels Messages XmlWriters and XmlReaders Message Encoders Dispatcher and Behaviors

  5. What is a Binding? • Abstraction of messaging functionality • Transport, security, transaction options, protocols • Creates a collection of BindingElement objects • Arrangement in collection is important NetTcpBinding b = new NetTcpBinding(); foreach (BindingElement el in b.CreateBindingElements()) { Console.WriteLine(el.GetType().Name); } // outputs TransactionFlowBindingElement // protocol BinaryMessageEncodingBindingElement // encoding WindowsStreamSecurityBindingElement // security TcpTransportBindingElement // transport

  6. What is a BindingElement? • Create Channel Listeners & Channel Factories • listeners on receiver / factories on sender • collectively known as Channel Managers • Collection creates a stack (listeners/factories) • via BindingContext and CustomBinding types • BindingContext keeps a mutable list of BindingElement objects in Collection • CustomBinding is isomorphic

  7. Walkthrough : Channel Factory NetTcpBinding BuildChannelFactory<T> BindingContext Channel Factory Stack CustomBinding TransactionFlowBindingElement TransactionFlowChannelFactory<T> BinaryMessageEncodingBindingElement BuildInnerChannelFactory<T> WindowsStreamSecurityBindingElement TcpTransportBindingElement TcpChannelFactory<T> Encoding and StreamSecurity absorbed by TcpChannelFactory via BindingContext

  8. Walkthrough : Channel Factory public abstract class Binding : IDefaultCommunicationTimeouts { public virtual IChannelFactory<T> BuildChannelFactory<T> ( BindingParameterCollection parameters) { BindingContext context1 = new BindingContext(new CustomBinding(this), parameters); IChannelFactory<T> factory1 = context1.BuildInnerChannelFactory<T>(); return factory1; } // creates BindingContext, then calls BuildInnerChannelFactory } public class BindingContext { public IChannelFactory<T> BuildInnerChannelFactory<T>() { return this.RemoveNextElement().BuildChannelFactory<T>(this); } // removes B.E. from list, then calls BuildChannelFactory on it } public class MyBindingElement : BindingElement { public virtual IChannelFactory<T> BuildChannelFactory<T>(BindingContext c) { return new MyChannelFactory<T>(c); // ctor calls context’s } // returns the Channel Factory // BuildInnerChannelFactory }

  9. Agenda Bindings Channel Managers Channels Messages XmlWriters and XmlReaders Message Encoders Dispatcher and Behaviors

  10. What is a Channel Factory? • Create sending Channels • Stack of Channel Factories creates Channel stack • Channel Factory stack is opaque • GetProperty<T> allows some query capabilities • Each Channel Factory in stack: • Refers to the next Channel Factory • Delegates GetProperty<T> calls when unknown • EndpointAddress needed in channel stack • Uri for Via can be used as well

  11. What is a Channel Listener? • Listens for incoming messages & Creates receiving channel stacks • Bottom-most Channel Listener listens on transport • Embrace “Accept” semantics similar to sockets • “Accept” returns a • Channel Listener stacks are opaque • Symmetry with Channel Factory design

  12. Walkthrough : Channel Stack From a Channel Factory: Channel Factory Stack CreateChannel Channel Stack TransactionChannelFactory<T> TransactionChannel<T> CreateChannel TcpChannelFactory<T> TcpChannel<T> From a Channel Listener: Channel Listener Stack AcceptChannel Channel Stack TransactionChannelListener TransactionChannel<T> TcpChannelListener TcpChannel<T> AcceptChannel message passing to channel stack not precise

  13. Agenda Bindings Channel Managers Channels Messages XmlWriters and XmlReaders Message Encoders Dispatcher and Behaviors

  14. What is a Channel? • Sends and/or receives Message objects • For specific transport or protocol functionality • Commonly stacked w / other Channel objects • Have shape described by interfaces • MEP (datagram, request/reply, duplex) • Composition of channel stack dictates messaging functionality

  15. CreateSequence CreateSequenceResponse (ID) Sequence (ID, Msg #1) X Sequence (ID, Msg #2) Sequence (ID, Msg #3, LastMessage) SequenceAck (ID, Msg #1, Msg #3) Sequence (ID, Msg #2, AckRequested) SequenceAck (ID, Msg #1 - Msg #3) TerminateSequence (ID) Consider WS-RM Sender Receiver

  16. Walkthrough: WS-RM Sending Application Client Channel Stack ReliableOutputSessionChannel Sequence (#2, LastMessage) CreateSequence / CreateSequenceResponse Sequence (#1) Ack (Msg #1-2) TerminateSequence HttpRequestChannel<T> Receiving Application

  17. MEPs and The Channel Layer • Channel Managers and Channels have shape • Shape represents the supported MEP(s) • Datagram, Request/Reply, Duplex • WCF represents shape via interfaces • Datagram: IInputChannel, IOutputChannel • Request / Reply: IRequestChannel, IReplyChannel • Duplex: IDuplexChannel • Sessionful variants also exist • Interfaces have common type hierarchy

  18. Shapes and Interfaces public interface IInputChannel : IChannel, ICommunicationObject { Message Receive(); // standard Begin / End methods also exist (and timeouts)... } public interface IOutputChannel : IChannel, ICommunicationObject { void Send(Message msg); // standard Begin / End methods also exist (and timeouts)... } public interface IDuplexChannel : IInputChannel, IOutputChannel, IChannel, ICommunicationObject { } public interface IRequestChannel : IChannel, ICommunicationObject { Message Request(Message msg); // standard Begin / End methods also exist (and timeouts)... } // IReplyChannel omitted for clarity

  19. ICommunicationObject • Channels and Channel Managers have a common state machine (also Faulted state) • Predictable state transitions

  20. Agenda Bindings Channel Managers Channels Messages XmlWriters and XmlReaders Message Encoders Dispatcher Behaviors

  21. The Message Type • Fundamental unit of communication • Channel layer interacts with Message objects • Seldom surfaces to the contract • CLR abstraction of a SOAP message • Body can be streamed, headers buffered • Can do non-SOAP formats (POX, JSON) public abstract class Message : IDisposable { public static Message CreateMessage(MessageVersion v, String a) {…} // lots of factory methods public void WriteMessage(XmlDictionaryWriter writer) {} // lots of write and read methods public abstract MessageHeaders Headers { get; } }

  22. Envelope / Addressing Versions • EnvelopeVersionidentifies SOAP specs • 1.1, 1.2, none • AddressingVersionidentifies WS-Addressing • Aug 2004, 1.0, none • MessageVersionwraps both • None == no SOAP please

  23. Agenda Bindings Channel Managers Channels Messages XmlWriters and XmlReaders Message Encoders Dispatcher and Behaviors

  24. XmlDictionaryWriter • An abstract type derived from XmlWriter • Wraps a System.IO.Stream • Created via factory methods • Specialized for binary, MTOM, text, JSON MemoryStream stream = new MemoryStream(); XmlDictionaryWriterdictionaryWriter = XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8, false); dictionaryWriter.WriteElementString("localname", “http://namespace", "someValue"); dictionaryWriter.Flush();

  25. XmlDictionaryReader • An abstract type derived from XmlReader • Wraps a System.IO.Stream or buffer • Created via factory methods • Specialized for binary, MTOM, text, JSON // Continued from previous slide stream.Position = 0; XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(stream); reader.Read(); Console.WriteLine(reader.ReadOuterXml());

  26. Encoding Sample - Text MemoryStream stream = new MemoryStream(); using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8, false)) { writer.WriteStartDocument(); writer.WriteElementString(“SongName”, “urn:ContosoRockabilia”, “Aqualung”); writer.Flush(); } // then read from Stream XmlDictionaryWriter (Text-UTF8) wrote 97 bytes 3C-3F-78-6D-6C-20-76-65-72-73-69-6F-6E-3D-22-31-2E- 30-22-20-65-6E-63-6F-64-69-6E-67-3D-22-75-74-66-2D- 38-22-3F-3E-3C-53-6F-6E-67-4E-61-6D-65-20-78-6D-6C- 6E-73-3D-22-75-72-6E-3A-43-6F-6E-74-6F-73-6F-52-6F- 63-6B-61-62-69-6C-69-61-22-3E-41-71-75-61-6C-75-6E- 67-3C-2F-53-6F-6E-67-4E-61-6D-65-3E data read from stream: <?xml version="1.0" encoding="utf-8"?> <SongNamexmlns="urn:ContosoRockabilia"> Aqualung </SongName>

  27. Encoding Sample - Binary MemoryStream stream = new MemoryStream(); using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateBinaryWriter(stream, null, null)) { writer.WriteStartDocument(); writer.WriteElementString(“SongName”, “urn:ContosoRockabilia”, “Aqualung”); writer.Flush(); } // then read from Stream XmlDictionaryWriter (Binary) wrote 43 bytes 3F-08-53-6F-6E-67-4E-61-6D-65-04-15-75-72-6E-3A-43- 6F-6E-74-6F-73-6F-52-6F-63-6B-61-62-69-6C-69-61-A1- 08-41-71-75-61-6C-75-6E-67 data read from stream: N/A 

  28. Agenda Bindings Channel Managers Channels Messages XmlWriters and XmlReaders Message Encoders Dispatcher and Behaviors

  29. From Message to the Wire • Known as Encoding • Via MessageEncoder and XmlWriter • MessageEncoder use Message.WriteMessage • Message.WriteMessage uses XmlWriter public class MyEncoder : MessageEncoder { public override void WriteMessage(Message msg, Stream stream){ XmlWriter writer = XmlWriter.CreateWriter(stream); msg.WriteMessage(writer); writer.Flush(); } // other members omitted }

  30. From the Wire to Message • Known as Decoding • Done via ReadMessage • uses one of the Message.CreateMessage overloads • CreateMessage overload accepts an XmlReader public class MyEncoder : MessageEncoder { public override Message ReadMessage(Stream st, Int32 s, String ct){ XmlReader reader= XmlReader.Create(st); MessageVersion version = MessageVersion.Soap12WSAddressing10; return Message.CreateMessage(reader, s, version); } // other members omitted }

  31. Walkthrough: Message-Wire-Message Message Channel Channel Message Encoder Message Encoder WriteMessage ReadMessage Message XmlWriter Bytes XmlReader Message Bytes Receiver Sender

  32. Channel Layer Service demo

  33. Agenda Bindings Channel Managers Channels Messages XmlWriters and XmlReaders Message Encoders Dispatcher and Behaviors

  34. About the Dispatcher • In the abstract, the Dispatcher hides from the receiver the fact that the receiving application is receiving messages • The Dispatcher is the realm of the contract • Messages go in, Parameters come out, and a method is invoked Receiver Receiving Application Parameters Dispatcher Protocol / Shaping / Transport Channels

  35. Method2(…) Operation Invoker DispatchOperation Message Formatting Service Behaviors Operation Selector Message Inspection Extending the Dispatcher Overview Method1(…) Operation Behaviors DispatchOperation Parameter Inspection DispatchRuntime Channel

  36. Important Types for Extending the Dispatcher • To extend the Dispatcher, define a type that implements one of the following • IOperationInvoker • Invokes method on target object • IDispatchMessageFormatter • to control format of the Message • IDispatchOperationSelector • to select operation on target object • IDispatchMessageInspector • to inspect the Message • IParameterInspector

  37. Steps to Extend the Dispatcher • Define a type that implements one of the previous interfaces • Define a type that implements one of the Behavior interfaces and instantiates the type in Step # 1 • Add the Behavior from Step #2 to the description via the appropriate place in the ServiceDescription • OPTIONAL – add configuration support • OPTIONAL – add support for attribute annotation

  38. IOperationInvoker • Enables control over the invocation of a method on the receiving object public interface IOperationInvoker { bool IsSynchronous { get; } object[] AllocateInputs(); object Invoke(object instance, object[] inpts, out object[] outputs); IAsyncResult InvokeBegin(object instance, object[] inpts, AsyncCallback cbck, object state); object InvokeEnd(object instance, out object[] outputs, IAsyncResult result); }

  39. IDispatchMessageFormatter • Enables control over received Message deserialization and outbound Message serialization • SerializeReply returns a serialized Message object • DeserializeRequest returns an Object deserialized from the Message • MessageVersion fed from the Binding • SerializeReply is not invoked if operation is OneWay public interface IDispatchMessageFormatter { void DeserializeRequest(Message msg, object[] parameters); Message SerializeReply(MessageVersion version, object[] parameters, object result); }

  40. IDispatchOperationSelector • Enables the selection of a particular DispatchOperation • SelectOperation returns the name of the method associated with the DispatchOperation • Normally loaded from the ContractDescription public interface IDispatchOperationSelector { String SelectOperation(ref Message message); }

  41. IDispatchMessageInspector • Enables a last view of the Message before it is sent into the Channel stack and at the point when the reply surfaces • Notice that the Message is passed by reference • Be careful of Message state transitions • Request and Reply messages can be correlated manually • If the operation is OneWay, BeforeReceiveReply not invoked public interface IDispatchMessageInspector { Object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContextinstanceContext); void BeforeSendReply(ref Message reply, object correlationState); }

  42. IParameterInspector • Enables the inspection of parameters before the request is deserialized or the reply is serialized • BeforeCall invoked before the Message is deserialized into parameters • AfterCall invoked after the reply is sent • If the operation is a OneWay operation, then AfterCall is not invoked • BeforeCall and AfterCall can be correlated via an Object public interface IParameterInspector { void AfterCall(String operationName, Object[] outputs, Object returnValue, Object correlationState); Object BeforeCall(String operationName, Object[] inputs); }

  43. What Order Are Interceptors Invoked? IDispatchOperationSelector IDispatchMessageInspector IOperationInvoker IDispatchMessageFormatter IParameterInspector Sender IOperationInvoker IParameterInspector IDispatchMessageFormatter IDispatchMessageInspector

  44. Behaviors demo

  45. Evaluation Forms

  46. Questions?

More Related