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>
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.