Saturday, February 28, 2009

WCF: Part 1

WCF service, WCF service class or just a sevice are all used interchangeably here to mean a WCF service class you want to expose to the world. Client and WCF client are also used interchangeably. A WCF client may or may not be a WCF service also - if it is, the term "client" is being used in the context of making a call to another service.

What is WCF?

WCF provides a runtime environment to expose your CLR types as services and to consume other services as CLR types.

How you turn a CLR class into a WCF service is easy using WCF attributes, a WCF host, WCF runtime and some prescribed methods to expose your service as an interface (aka endpoint).

Although a windows service can be developed without WCF, a WCF service is very easy to develop due to off-the-shelf facilities such as hosting, service instance management, asynchronous calls, reliability, transaction management, disconnected queued calls and security.

WCF clients and services interact using SOAP messages which are independent of transport protocols like HTTP, tcp, msmq, named pipes etc. Thus, a WCF client can interact with a non-WCF service while a WCF service can interact with a non-WCF client (though if both services and clients can be developed with WCF, you get WCF-specfic advantages mentioned above).

A WCF client never directly interacts with a WCF service - it always uses a proxy (allowing location transparency)

A WCF client can easily interact with a WCF service that may reside in the same app domain, across app domains, across processes or across machines.

A WCF Service Has >1 EndPoints, Where an Endpoint is a True Interface

Endpoint is a term to encapsulate 3 of the properties that describe a service class you want to expose to the outside world. A=Address (where), B=Bindings (how) and C=Contract (what). In other words, an endpoint is an interface to a WCF service class.

An endpoint has inherently nothing to do with service class code. A host is required to expose the endpoint.

Address: is platform-neutral and specifies location and transport protocol to use with the service class. Format is as follows.

[transport]://[machine/domain][:optional port]/[optional URI] i.e.
http or net.tcp or net.pipe or net.msmq://localhost[optional :8001]/[optional myservice]

Bindings: A canned set of choices regarding transport protocol, message encoding, communication pattern, reliability, security, transaction and interoperability for the service class.

A client must use the same binding values as the service class. A single service class can support multiple bindings as long as each is hosted on a different address. You can use OOB bindings or OOB bindings with tweaked-in properties (on things like transaction propagation, reliability, security etc.) or write your own from the scratch.

WCF-provided OOB Bindings
BasicHttpBinding (protocol - http/s; encoding - text, mtom; interoperable - yes)
or the related BasicHttpContextBinding
WSHttpBinding (protocol - http/s; encoding - text, mtom; interoperable - yes)
or the related WSHttpContextBinding
WSDualHttpBinding (protocol - http; encoding - binary; interoperable - no)
NetTCPBinding (protocol - tcp; encoding - binary; interoperable - no)
or the related NetTCPContextBinding
NetNamedPipeBinding (protocol - ipc; encoding - binary; interoperable - no)
NetMSMQBinding (protocol - msmq; encoding - binary; interoperable - no)

Binary encoder used in WCF bindings is proprietary to MS so don't write a custom parser for the binary encoder on non-WCF platforms. Use a decision tree (starting with "are client and service both WCF?") to use the most appropriate binding for your service.

Contracts: is platform-neutral and specifies what a service class does.

4 types of contracts exist. service, data, fault and message (message contract is not recommended to be used. A better alternative is to use custom headers).

WCF Hosting

A host exposes an endpoint or multiple endpoints of a service class. A host process can host multiple WCF service classes and a single WCF service class can be hosted in multiple host processes.

A host must be running with service types already registered before a client call comes in.

A host can be an IIS, WAS (on Vista or Win2008), a Windows NT service, a console app or a Windows forms app (the latter 3 are in-proc hosts where service and clients must run in the same process. They also happen to be self-hosts because the services are not being hosted from an external process like IIS or WAS. Instead the services are hosted by WCF class ServiceHost).

Self-Hosting using ServiceHost class

[ServiceHost is WCF-provided but Juval's generic version i.e. ServiceHost<T> : ServiceHost that utilizes extension methods provides an easier model for self-hosting. See here for details]

Note that the purpose of a host is to expose the endpoints, so think of how you can expose the endpoint (address, binding and contract) of each of your service class and with self-hosting, it means your host is going to be the WCF-provided ServiceHost class.

ServiceHost : ServiceHostBase : CommunicationObject implements ICommunicationObject

We use the methods (open, close, aynch open, close) and events defined within the ICommunicationObject interface and use them on the ServiceHost class to open the host, expose the endpoints and close the host programatically or using a config file or both.

Using programmatic approach, in the main() method (of an NT service code, a console app code or a Windows forms app code) , create a new instance of WCF-provided ServiceHost class passing in typeof(YourServiceClass), repeat with a new ServiceHost instance for each service class you want to expose, and call Open on the instance.

Use a new instance of ServiceHost for each different service class you want to expose.

Open() method on an instance of ServiceHost loads the WCF runtime and launches monitoring worker threads (to monitor for client calls) that handoff calls to worker threads from the I/O completion thread pool (100 of these exist by default). Close() method refuses future calls on the instance effective immediately but the ones being run in the instance are run to completion. For a graceful exit of all ServiceHost instances, call each one's Close() when the host process itself is shuttiong down (you can override timeout 0f 10 seconds that an instance of ServiceHost is given to gracefully exit when Close() is called).

Metadata Exchange

A service that does not publish metadata is like a .NET internal class i.e. a client can still call the service if it got hold of metadata through some other mechanism.

Since the host knows everything there is to know about your service class (the host is the one to set up the endpoint/s for your service class), the host can publish the metadata also if instructed to do so.

There are 2 ways to publish metadata - HTTP-GET or a dedicated endpoint. Using WCF, you add a behavior, programatically or administratively, to your service indicating it wants the host to publish its metadata over HTPP-GET. Recommendation: use the hosting code to check for metadata behavior in config file first and if there is none, use a new instance of ServiceMetadataBehavior and set HttpgetEnabled to true, still allow the config file to override.

MEX endpoint

There is no need to enable http-get (although no harm in doing so) if you can publish metadata over a special endpoint called MEX endpoint on the host - just assign an address (full or any registered base), binding (WCF provides http, https, tcp and ipc oob) and add the metadata behavior.

You can add one or multiple MEX endpoints for your service class administratively or programatically.

Recommendation: Use Juval's ServiceHost<T> to easily enable metadata both over http and thru a MEX endpoint.


Tuesday, February 24, 2009

Extension Methods

http://msdn.microsoft.com/en-us/library/bb383977.aspx

Extension methods enable you to "add" methods to existing types without creating a new derived type.

Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type.

Sam: When you look at the definition of the extended method, you will see the first parameter to be in the format of "this IMyInterface<T> var". This is the norm. From the client side, when you call the method, you ignore this first parameter (Intellisense in VS2008 will automatically and conveneiently hide this first parameter for you so that the method looks like any other instance method on a class).

In general, you will probably be calling extension methods far more often than implementing your own. A general guideline is that that you implement extension methods sparingly and only when you have to. Use inheritance instead. Sam: so why is Juval Lowy's extension methods (in his book "Programming with WCF") found within "public static class CollectionExtensions" of his ServiceModelEx library a good thing to use?

For client code written in C# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type.

You can use these methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called. At compile time, extension methods always have lower priority than instance methods defined in the type itself. In other words, if a type has a method named Process(int i), and you have an extension method with the same signature, the compiler will always bind to the instance method. When the compiler encounters a method invocation, it first looks for a match in the type's instance methods. If no match is found, it will search for any extension methods that are defined for the type, and bind to the first extension method that it finds.



Some available extension methods
The most common extension methods are LINQ standard query operators that add query functionality to IEnumerable collections and IEnumerable generic collections. So, by simply using System.Linq, you should see a whole lot of instance methods like OrderBy, Average on types like List, List, string[] etc.

Example: "OrderBy" extended method on any class that implements IEnumerable<T>

In System.Linq ns, OrderBy is overloaded and defined as

(1) public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
this IEnumerable<TSource&gt; source,
Func<TSource, TKey> keySelector)

(2) public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
this IEnumerable<TSource&gt; source,
Func<TSource, TKey> keySelector,
IComparer<TKey>comparer)

Also in System.Linq, IOrderedEnumerable is defined as

public interface IOrderedEnumerable<TElement> : IEnumerable<TElement>, IEnumerable

Using (1), from a client's perspective (where you ignore the 1st param), see how the method takes a delegate Func<TSource, TKey> variable that points to a method (could be anonymous or a lambda expression), quite possibly on the client.

Example showing various equivalent ways of calling the "OrderBy" method where its delegate variable parameter points back to a client method.

Assume you have a simple class Pet with 2 public members Name and Age.

Pet[] pets =
{
new Pet { Name="Barley", Age=8 },
new Pet { Name="Boots", Age=4 },
new Pet { Name="Whiskers", Age=1 }

};

//(1a)Explicitly defining the delegate variable Func<TSource, TKey> and pointing it to an explicit method

Func<Pet, int> del = MyFunctionMatchingtheDelegate;
IEnumerable<Pet> query = pets.OrderBy(del);

private static int MyFunctionMatchingtheDelegate(Pet p)
{
return p.Age;
}


//(1b)Implicitly using the delegate variable Func<TSource, TKey> and pointing it to an explicit method

IEnumerable<Pet> query = pets.OrderBy<Pet,int>(MyFunctionMatchingtheDelegate);



//(2a)Explicitly defining the delegate variable Func<TSource, TKey> and pointing it to an anonymous method
Func<Pet, int> del = delegate(Pet p)
{
return p.Age;
};
IEnumerable<Pet> query = pets.OrderBy(del);


//(2b)Implicitly using the delegate variable Func<TSource, TKey> and pointing it to an anonymous method
IEnumerable<Pet> query = pets.OrderBy<Pet, int>
(
delegate(Pet p)
{
return p.Age;
}
);


//(3a)Explicitly defining the delegate variable Func<TSource, TKey> and pointing it to a lambda expression
Func<Pet, int> del = pet => pet.Age;
IEnumerable<Pet> query = pets.OrderBy(del);


//(3b)Implicitly using the delegate variable Func<TSource, TKey> and pointing it to a lambda expression
IEnumerable<Pet> query = pets.OrderBy(pet => pet.Age);

In any case, the actual function (whether lambda expression, anonymous method or explicit method) is not executed until the foreach iterator is first accessed as follows.

foreach (Pet pet in query)
{
Console.WriteLine("{0} - {1}", pet.Name, pet.Age);
}


Notes
In each of the above examples, note we are using the IEnumerable<Pet> iterator even though the definition of OrderBy clearly implies IOrderedEnumerable<Pet>. I'm pretty sure you can use the IOrderedEnumerable in each of the above cases. What are the benefits of using IOrderedEnumerable over IEnumerable, if any?

The other overloaded OrderBy takes an an extra parameter IComparer. Create code examples for that.

Juval Lowy's numerous extension methods apply to IEnumerable<T> and to IEnumerable. Most of his methods also take .NET provided generic delegates like Converter, Action etc. as variables, thus allowing developers to create their own methods the delegates point to.


To Implement Your Own
http://msdn.microsoft.com/en-us/library/bb311042.aspx
(1) It is generally a good idea to extend an interface, not the class.
(2) Understand that if the method you are trying to add already has a matching instance method signature on a class, your extended method will never execute.
[This means, if the type changes and adds a new set of instance methods, one of which matches the extended method you already implemented, then all of a sudden, your extended method will never execute]
(3) Example:
namespace IT.ClientSystems.Extensions
{
using System;
using IT.ClientSystems.Interfaces;

// Define extension methods for any type that implements IMyInterface.
public static class Extension
{
public static void MethodA(this IMyInterface myInterface, int i)
{
Console.WriteLine("Extension.MethodA(this IMyInterface myInterface, int i)");
}

ClientSide: Assume ClassA implements IMyInterface and does not have an instance method called MethodA that takes an integer parameter.

using IT.ClientSystems.Extensions;
ClassA a = new ClassA();
a.MethodA(5);

(4) An advanced example would be for your extended method to take a generic delegate as one of the parameters like "OrderBy" method shown above. Many of System.Linq extension methods and those from Juval's personal library use generic delegate parameters. Common ones are Converter, Action, Predicate, Func etc.