IT:AD:WCF/Concepts:The Whole Picture:ServiceHosts
- Next:Definitions
Summary
WCF Services are hosted in IIS using ServiceHost.
Understand what a ServiceHost is First
Starting at the very beginning, let's cover what a ServiceHost is first.
Think of a ServiceHost as a self-contained WCF specific server for a single Service.
Each service will require a unique network address.
baseAddress to get to the root of the website (but don't take the analogy too far).
One instantiates a ServiceHost within the scope of a Windows Service or IIS, load it up with the definition of a single service and n endpoints, and turn it on. It responds to requests until the parent host (WS or IIS) tells it to stop.
FAQ:
- Can I host multiple Services per
ServiceHost?- No. Ref:forum
* Is it part of IIS or is it separate.
- Tricky question. It's both. (in IIS6 it's separate, in IIS7 its unified if you set the right settings). For most scenarios think of it as separate, one distinct server piggybacking on another server.
While working with*.svc's in the following sections, it will make things easier to remember that under the hood, no matter where you are hosting theservice(in IIS, WS, or other), eachserviceis getting oneServiceHostwhich corresponds to oneserviceconfiguration element in the server's config file.
3. Decide where to Host the ServiceHost
Until recently I would have said that hosting a ServiceHost within a Windows Service is the cleaner approach. But after reading this post I've changed my mind.
- Hosting in IIS:
- -: Slower start unless you set it to AlwaysOn
- +: Can takes advantage of IIS's richer architecture for load distribution mechanisms, etc.
- -: The page defines the
baseAddressof theService, and ignores any manual attempt to set it using:system.serviceModel/services/service/host/baseAddresses/add@vaseAddress="..."
- -: Medium to Difficult install strategy on a customer's infrastructure.
- Hosting in WS:
- +: Purer way of seeing things (sort of, still are a Service within a Service)
- +: Easier install strategy.
- +: Once started, first response is fast.
- -: Have to write everything yourself in terms of load distribution/ramp up, etc…no win really.
- +: You won't be able to use
HttpContextin your code or be Stateful (that's actually a good thing).
4a. Create a ServiceHost in WS
Because of the previous analysis, I'm going to skip this part.
4b. Create a ServiceHost in IIS
Having first encountered IIS when developing ASP.NET pages, almost every single developer makes the same mistake, seeing an IIS hosted *.svc page as basically the same thing as an ASP.NET webpage.
It isn't, and it doesn't work in at all the same way.
An *.svc in IIS is not a webpage – it's a entry point to ServiceHost, hosting a single service (see above), that sets the ServiceHost's baseAddress from the page's url relative to the root of the website. In other words, it's less like *
and more like *
.
The *.svc's markup is empty, bar one line that clearly says it is a ServiceHost (really can't miss it's meaning once you know to look for it):
<%@ ServiceHost Language="C#" Debug="true" Service="Examples.Service1" CodeBehind="Service1.svc.cs" %> //or if the code is in another dll: <%@ ServiceHost Language="C#" Debug="true" Service="Examples.Service1, SomeAssembly" %>
Note that:
- the
Serviceattribute defines the Service instance's Type's FullName. - the
CodeBehindhas nothing to do with WCF proper – it's just used for IIS's compilation on the fly. - the
serviceinstance theServiceattribute refers to (Service1), implements a service contract (IService1) that is not mentioned on this page (it's both in the codebehind, and in the config file).- The service contract will be important in a sec, when we get to discussing the service endpoint…
- the
servicecontract is just describing the functionality to expose to a client, not the actualbinding(ie protocol, authentication, etc.).- Therefore, to be usable by the ServiceHost, the
servicedefinition it already knows about from theServiceattribute has to be matched up and combined with the binding information in the site's config file. - That's done by matching the above
@Serviceattribute value to the thesystem.serviceModel/services/service@name="..."attribute in the config file.
TroubleShooting:
- if the
Serviceattribute doesn't match a class name, you'll getThe type 'X1', provided as the Service attribute value in the ServiceHost directive could not be found - if they don't match you'll get `Service 'NS.Service1' has zero application (non-infrastructure) endpoints. This might be because … no service element matching the service name could be found … or because no endpoints were defined in the service element.
Next: Definitions