Hi Guys,
This post is going to discuss some basic high level aspects of WCF. Below is a diagram of the architecture for it.
Some high level facts.
- Message Contract is the structure of an actual WCF Message, it describes the nature of the message
- A Data Contract is the PAYLOAD or actual data, which is embedded into the Message.
- The Service runtime is primarily concerned with processing the content of message bodies
- The message layer is concerned with “channels” and channel stacks (More than one channel)
There are two types of channels
Protocol Channel – Message Header Management – WS-Security/WS-Reliability
Transport Channel – How data is communicated/translated/encoded/decoded on the wire. Http, Netmsmq - Hosting – WCF can be hosted in a Windows Service, Executable, IIS WAS or IIS. You can even run it inside a NServiceBus host if you wanted.
We all know the ABC’s of WCF.
A service will need an Address, Binding and a Contract. But there is allot more to WCF than meat the eye.
Behaviors
Control various run-time aspects of a service, an endpoint, a particular operation, or a client. You have common behaviors affect all endpoints globally,
Service behaviors affect only service-related aspects,
Endpoint behaviors affect only endpoint-related properties, and
Operation-level behaviors affect particular operations.
e.g. One service behavior is throttling, which specifies how a service reacts when an excess of messages threaten to overwhelm the system. An endpoint behavior, such as where to find a security credential.
In regards to service behaviours, one aspect that is overlook is Instance and Concurrency modes. Read more about it further down in this article.
Instances and Concurrency
This is often overlook, always be aware of how you write your WCF service and ensure the code is thread safe and can handle multiple instances and concurrency aspects, else you might find your WCF services not scalable! These are things you should always think about BEFORE your write the service. You should read this article to get a better understanding of it.
http://msdn.microsoft.com/en-us/library/ms731193.aspx
Have a read, and ensure you classes etc are thread safe so they can scale, no shared variables etc in your WCF code that maintain a state at the service layer, you will find yourself in deep water. You can use sessions, instances or concurrency mode combinations to control these aspects.
Here is an interesting example of customizing this option, which should get you thinking about how you combine these sort of behavioural modes!
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)] public class ProductsService : IProductsService { //Your Service Logic }
Per-call services are the Windows Communication Foundation default instantiation mode. When the service type is configured for per-call activation, a service instance, a common language runtime (CLR) object, exists only while a client call is in progress. Every client request gets a new dedicated service instance. This keeps the lifetime of objects short as possible.
- The client calls the proxy and the proxy forwards the call to the service.
- Windows Communication Foundation creates a service instance and calls the method on it.
- After the method call returns, if the object implements IDisposable, then Windows Communication Foundation calls IDisposable.Dispose on it.
Single: Each instance context is allowed to have a maximum of one thread processing messages in the instance context at a time. Other threads wishing to use the same instance context must block until the original thread exits the instance context.
Can you see something here, this combination is irrelevant? Since PerCall is here,the proxy will never allow multiple threads, since the proxy will know there is an instance already, so some combinations will never need to be explicit, such as the redundant attributes in the above code.
Dispatcher Runtime And Client Runtime
What if you want to customize Wcf? How about introducing a custom Encoding/Decoding Algorithm or custom compression/validation system or a custom error handler for legacy systems?
Lets get even more fancy, how about a custom instance provider that can hydrate and dehydrate WCF instances to and from a database for long running transactions, similar to the idea of Saga’s in NServiceBus…
This can all be done on the client runtime or dispatcher on the service.
There is allot going on in WCF and there is several posts on making a Hello World WCF service, lets skip all that and get down to extensibility of WCF. We will focus on the dispatcher and message inspectors. Lets check what we can do firstly on the client side and then on the server side.
Here is an overview of the architecture.
From the above diagram you can see that WCF is very extensible, there are hooks in the architecture where you can extend the functionality of WCF.
The client runtime is responsible for translating method invocations into outbound messages, pushing them to the underlying channels, and translating results back into return values and out parameters.
This runtime model presents different service model extensions to modify or implement execution or communication behavior and features client or dispatcher functionality such as message and parameter interception, operation selection, message encoding and other extensibility functionality.
In the service, the dispatcher runtime is responsible for pulling incoming messages out of the underlying channels, translating them into method invocations in application code, and sending the results back to the caller. This runtime model presents different service model extensions to modify or implement execution or communication behavior and features client or dispatcher functionality such as message and parameter interception, message filtering, encoding and other extensibility functionality.
There is numerous examples here:
http://msdn.microsoft.com/en-us/library/ff183867.aspx
Here is an example of a WCF Service using a Behaviour for JSON Serialization. Notice the different level of behaviours from EndPoint Behaviours/Service Behavoirs etc, also notice we have a JSON which is done in the EndPoint Behaviour. Also notice the bindings, we have different types for different clients, .Net can use the webHttpBinding and Java clients can use the BasicHttpBinding.
<system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="BaseBehaviors"> <serviceDebug includeExceptionDetailInFaults="true" /> <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" httpGetUrl="Products/GetList" httpsGetUrl="Products/GetList" /> </behavior> </serviceBehaviors> <endpointBehaviors> <behavior name="BaseHttpEndpointBehavior"> </behavior> <behavior name="jsonBehavior"> <enableWebScript /> </behavior> </endpointBehaviors> </behaviors> <serviceHostingEnvironment aspNetCompatibilityEnabled="false" /> <services> <service behaviorConfiguration="BaseBehaviors" name="Romiko.MyService"> <endpoint name="ProductService" address="Products" behaviorConfiguration="BaseHttpEndpointBehavior" binding="basicHttpBinding" bindingConfiguration="" contract="Romiko.IProductsService" /> <endpoint name="ProductServiceSSL" address="ProductsSSL" behaviorConfiguration="BaseHttpEndpointBehavior" binding="basicHttpBinding" bindingConfiguration="SecureSSL" contract="Romiko.IProductsService"> </endpoint> <endpoint name="ProductsServiceJSON" address="ProductsJSON" behaviorConfiguration="jsonBehavior" binding="webHttpBinding" bindingConfiguration="" contract="Romiko.IProductsProductsService" /> <endpoint name="ProductsServiceJSONSSL" address="ProductsJSONSSL" behaviorConfiguration="jsonBehavior" binding="webHttpBinding" bindingConfiguration="SecureSSLWeb" contract="Romiko.IProductsService"> </endpoint> <host> <baseAddresses> <add baseAddress="http://localhost/Products" /> <add baseAddress="https://localhost:443/Products" /> </baseAddresses> </host> </service> </services> <bindings> <basicHttpBinding> <binding name="SecureSSL"> <security mode="Transport"> <transport clientCredentialType="None"/> </security> </binding> </basicHttpBinding> <webHttpBinding> <binding name="SecureSSLWeb"> <security mode="Transport"> <transport clientCredentialType="None"/> </security> </binding> </webHttpBinding> </bindings> </system.serviceModel>
Well, I hope this helps you get your toes a little deeper into WCF, so the next time you write a WCF service you can nut out all the architectural principles BEFORE writing the code.
References:
This is my first time pay a visit at here
and i am actually impressed to read all at one place.