I want to know what happens when I create an instance of a ServiceHost class?
What it does ?
The ServiceHost (whether instantiated by yourself directly, or whether you delegate that job to IIS/WAS) is the runtime environment for your WCF class - which is just a simple .NET class after all (which needs to run somewhere).
The ServiceHost basically provides all the "plumbing" around your WCF service - creating the endpoints and the listeners on those endpoints to listen for messages and catch those as they come in; it provides the whole channel stack from the transport level through all the layers of WCF up through deserializers on to the dispatcher which then decides which class and which method on that class to call, and so on.
In WCF, in your service class, you write only the actual busienss logic of your service - the ServiceHost and all its classes around it handle all the nitty-gritty details of the receiving of messages and sending back of responses etc.
Marc
Typically the ServiceHost class is used to host your WCF services in a standalone app (such as a console app), if you are not using IIS or Windows Activation Service (WAS).
In simple terms it will deal with the COMs (listening for messages for a particular service).
You can also derive from ServiceHost to add customization if required, in combination with a specialization of ServiceHostFactory.
See MSDN example.
HTH
Phil'
It creates channels that are responsible for things like reliable transfer and security. It listens for incoming messages and calls your operation methods.
Related
It is my understanding that a WCF service configured for net.msmq will not run as an HttpApplication when hosted in IIS/WAS, which means you don't get the events in Global (Application_Start being the important one). Am I correct in this regard?
Does using Windows Server AppFabric to auto-start the service hit the service over HTTP, causing the Application_Start event to fire? If so, is this reliable?
I guess my real question is, where is the "proper" place for initialization code for a non-HTTP WCF service?
Particularly (since the right place may be different for different stuff):
IoC registrations
log4net initialization
Verifying the MSMQ queue exists locally (as Juval Lowy suggests in his WCF book)
Follow-on question: Do the events in a custom IServiceBehavior fire on every request or only once at startup? What about ServiceHost.OnOpening() - every request or only once at startup? (My testing shows it's only once, but does anyone know where the WCF "lifecycle" is documented, because I can't seem to find it anywhere.)
I can't verify that WCF services hosted in IIS/WAS can't be configured to support Application_Start but it is not required to do what you want. I'd recommend you create a custom ServiceHost in conjunction with a custom ServiceHostFactory (for WAS). This approach is documented in an MSDN article and this blog post. Using this approach, you can host your service in IIS/WAS, a Windows Service or a console app because the initialization process will be the same.
A little background info -
I'm trying to host a RESTful WCF service on Azure. As I understand, unless I have the ASP.NET type hosting on the role, I don't really need the global.asax class (which has the application_start method).
From basic prototyping, all I needed was the svc file and the implementation behind it and it automatically gets initialized on role startup (I mean, hosted up on IIS).This is great because I need no extra code other than web.config and my service is up and running. I don't need to create a new service host and start listening on it, etc. I'm able to deploy the role and POST messages to my service.
The problem -
I have custom logging and initialization classes implemented that I need to initialize when my service starts up. I configured my service to be a singleton and I'm not sure where I should put my custom initialization components.
Without an explicit application start method and my service configured as a singleton, can I assume that when the first request comes in, my service constructor gets called? (along with all my custom initialization?).
can I assume that when the first request comes in, my service constructor gets called?
Yes, but you should ask yourself whether you really want your service to run as a singleton. If you're happy with this then it will work fine; if you don't want it to run as a singleton then you should look into Russell's answer using a custom factory.
Look at Should WCF service typically be singleton or not? for some discussion about whether WCF services should be singletons. You need to decide for your situation, but generally WCF services are not singletons unless they need to be.
To implement a custom factory, see this MSDN link Extending Hosting Using ServiceHostFactory. As the link describes, extend the service host factory like so
public class DerivedFactory : ServiceHostFactory
{
public override ServiceHost CreateServiceHost( Type t, Uri[] baseAddresses )
{
return new ServiceHost(t, baseAddresses )
}
}
And then specify your factory in the ServiceHost directive
<% # ServiceHost
Service="MyNamespace.MyService"
Factory="MyNamespace.DerivedFactory" %>
You're looking for ServiceHostFactory. You can add a part to the SVC file to use a factory, where you can do any logging etc. you may need.
I have used this in the past to start a background worker to launch a separate thread for some background work.
http://msdn.microsoft.com/en-us/library/system.servicemodel.activation.servicehostfactory.aspx
Hope this helps you get where you need to be. :)
Where is the best place to put code for when a WCF service is just started up? Similar to Page_Load in a web application.
The service implementation constructor would be the obvious place but it also depends on your hosting model
1) run once code: IIS hosting = global.asax; self-hosting = Main / OnStart
2) run once per service instance: constructor of service class
3) Something more exotic: implement IInstanceProvider
In the class constructor of the service implementation.
Honestly the best place is the constructor and/or static constructor for your service class (for static members). There is no other WCF specific lifecycle event that will notify your service implementation when it's being created by the service host.
Now, if you're talking about the creation of services generically, that would mean you're willing to hook into the WCF runtime and there you can do things like get in the middle of the instance creation with a custom IInstanceProvider implementation.
I have a windows service that picks up messages from various MSMQs. The service picks up the messages from the queues, and then executes a specific workflow based on the queue the message came in from. Is it possible to configure a WCF service to accept a message from an endpoint and place it in a queue? I would like for the service to have multiple endpoints, and depending on which endpoint received the message, the message would be placed in a different queue. I have seen things about netMsmqBinding but so far I haven't been able to determine if this is meant for the use I am thinking about.
Any help is appreciated,
Mike
Am I getting this correctly - you want to have
a WCF service exposed to the outside world using multiple endpoints
depending on which endpoint the message comes into the WCF service, it should put those messages into separate MSMQ queues?
You can definitely have a WCF service that will expose any number of endpoints to the outside and that would drop incoming messages into an MSMQ queue. I'm just not sure whether you'll be able inside the WCF service method to know which endpoint the request came in on..... typically, the WCF service class doesn't know anything about where the request came from (and typically doesn't need to know...).
I see a few approaches to this:
have multiple services, one for each (type of) endpoint; they can share all their code and everything, but if you separate this into separate service classes, then each service class would inherently know what endpoint it serves, and thus could know what MSMQ queue to put the info into
find a way to send some header information along with the message that somehow tells you where to put the messages
in WCF 4.0, you might be able to do something with the new WCF Routing Service.... not quite sure how that would work, however - since it would also require some kind of "hint" to know which endpoint it was called on and how to route the incoming message
The way I was able to go about this was by creating a custom ServiceHost class that I could pass a configuration name to. This is an alternative to the default implementation that uses the Service Implementation type name to locate the configuration. This allowed me to run multiple instances of the same implementation on the same machine. In addition to that, inside the custom service class I added a custom MessageInspector that would attach itself to every endpoint to listen for messages. I then use the IDispatchMessageInspector.AfterReceiveRequest() method to take the incoming message and then place it into a queue that I define inside my configuration. A little complicated, but it works perfectly for our scenario.
net.msmq bindings allow a WCF client to write directly to an MSMQ queue, even if the queue-reading WCF service is not live -- it doesn't even have to exist. net.msmq bindings also allows automagic reading from queues. No use of MessageQueue to write to, or read from, a queue.
I am developing a solution with multiple WCF services which all communicate among themselves, even though they are of different types. The services connect to one another through the ChannelFactory generic interface, and every service is hosted inside a ServiceHost.
My question is if it would be correct to use a callback contract among the servers to communicate with one another and if so how would such a solution look.
Currently I don't like the implementation because every service needs to host a couple of endpoints with different interfaces some for other services and some for other clients.
When I tried to implement the callback contract inside a service class that was hosted inside a ServiceHost it failed.
First of all, whenever you post a question saying, "it failed", you need to tell us in what way it failed. If there was an exception, then you need to post the entire exception, including all InnerException instances, by posting the result of ex.ToString().
To your problem, I'd implement a service contract that represents the part of each service that needs to talk to the other services. There would also be a callback contract associated with this service contract.
That way, it's as though each service operates a miniature service intended only for service-to-service communications. They can then each do their own thing with the information that is passed between the services.