Can WCF Self-hosting service have initialization logic? - wcf

I have created a WCF Service Library in VS2010 and can run the service by selecting Debug->Start New Instance from project's right click menu.
Can I further define some initialization logic that would be executed before the service is started?
EDIT:
What I try to achieve is to initialize NHibernate and several other elements so that they are ready when the service starts.

If you self-host (i.e. write your WCF host yourself) - sure, no problem, do whatever you need to do before you call .Open() on the ServiceHost.
ServiceHost host = new ServiceHost(typeof(YourServiceClass));
// do your initialization here
........
host.Open();
If you're using IIS or WAS or AppFabric to host your WCF service: I doubt it, since those are "message-based" activation server, e.g. they start up a service host to handle a request on demand, when a request comes in, and I'm not aware of any extension points to get into the initialization process if you're using the regular ServiceHost class for hosting.
That said: you can of course define your own descendants of ServiceHost - derive your custom service host from ServiceHost or ServiceHostBase - those should give you points to get into the initialization process (overriding the InitializeRuntime method, or responding to the Opening event).
See the MSDN docs on:
ServiceHostBase abstract base class for custom service hosts
ServiceHost as a concrete implementation of ServiceHostBase to possibly inherit from
Custom Service Host explaining the ins and outs of how to achieve this all

Related

Simplify Using IOC Container with WCF

In article after article after article, any discussion of using an IOC Container (Unity, Windsor, etc.) with IIS involves the creation of a custom ServiceHostFactory and a custom ServiceHost.
The only reason I can see for that, is so that a custom service behavior, with an IInstanceProvider-related payload, can be applied to all services. So I'm trying to understand why the whole affair is not simplified by having an anonymous service configuration. Such configuration would allow a custom behavior to be applied to all services without using a custom ServiceHostFactory and custom Service Host.
That said, the only reason I can imagine a custom service host would be necessary is if the custom IInstanceProvider is recycled with each WCF instance or context instance. Certainly I would want IOC Container bindings to be established only once for each launch of my IIS ServiceHost rather than repeatedly or irregularly.
If my custom IInstanceProvider is indeed being recycled sporadically, then I could put my IOC Container into a custom service host - to insure that it will stick around as long as possible.
But again, if my custom IInstanceProvider will last as long as the in-built service host, then why not just skip the custom service host factory and custom service host?
In fact, taking this a bit further, if I were to put my IOC Container into a static member of my custom IInstanceProvider, then it wouldn't matter if the IInstanceProvider was being recycled irregularly. It comes full-circle: why do I need or want a custom ServiceHostFactory and custom ServiceHost to use an IOC Container with WCF?
Well. That's because most IoC/WCF integrations (like mine) does more than just creating your service (with it's dependencies).
Custom lifetimes / Disposal
Everything should get clean up properly when a request have ended. Your servcice and your IoC classes uses different lifetimes.
The end of a request can't be detected just with the help of an InstanceProvider.
IContractBehavior / IServiceBehavior
You can register behaviors in the container and automatically get them added to your WCF service.
Personally, i'm a fan of using a design where you don't need any ServiceHostFactory, ServiceHost, ServiceBehavior, and InstanceProvider combination and where you don't have to register the factory in your .svc file. I like my WCF service as just a really thin layer on top of a message passing architecture, and this saves you from using this WCF integration stuff. You can read more about such a design here.
Interesting question! The only reason I could think of for doing it this way is that you don't want to clutter up your app.config with items that are never going to change (i.e. the IoC container used by your WCF services). I try to restrict my use of the app.config to things that an end-user / developer might conceivably want to change without recompiling (in most cases, not much). This makes it more readable, and it is usually easier to specify configuration programmatically as there is better support for intellisense and compile-time checking within program code as opposed to configuration files.
However, this argument might not apply to the first article you linked to, because they're actually setting up their IoC container through the app.config. So it might be a double standard in this case. I've never really understood why people want to set up all their dependencies through external configuration files anyway. Storing static configuration in the app.config just seems like overkill to me in most cases.

WCF constructor Service Type via DI

I'm currently trying to build a small App-Server which shall host multiple WCF services. These services (and their dependencies of course) should be instantiated by an DI/IoC Container (currently LightCore but since I am using it via the CommonServiceLocator it should be easy to exchange).
Unfortunately I stumbled onto a problem. Obviously I have to create ServiceHost instances to host mentioned WCF services. I already built a customized InstanceProvider and ServiceBehavior to handle all dependencies of the services, BUT the Constructor of ServiceHost needs the Service Type of the service to host. At this point in my program, I only know the Interface Type, since only the DI container knows which Service implementation is currently being used.
A cheap method would be to create a "dummy" instance of the service type via Service Locator and give the ServiceHost constructor the output of myDummyInstance.GetType(), but that just hurts to look at, useless instantiation and usage of Service Locator instead of DI...there has to be a better way.
Any ideas anyone? :)
There are multiple ways how to do that.
The way I like is very simple. You will not resolve contract of your service but service implementation itself because simply that is what WCF expects. All IoC containers I used are able to resolve type itself and fill its dependencies.
Another way is little bit more hack. When you call the constructor of service host you will resolve type of the service contract by call like ServiceLocator.Resolve<IContract>().GetType(). It is ugly but it is much more clean then creating dummy implementations. Moreover you never know if the passed type is not used for something else in the infrastructure so passing dummy type can be dangerous.

WCF life cycle for webservice and a singleton WCF service?

How does the life cycle looks like for the following :
WCF Webservice(http)
If I got this correct the service will be created for every call?
WCF netTCP (also hosted in IIS) as singleton
Is it correct thtat the WCF service will be created on the first call and then never go down? Or will it go down when there is no connections for a while? And if so, where do I set this timeout? The service in my case is keeping state for the client so what will happen if a client connects but is idle so long that it excedes the timeout?
For the 1) the service will be created on every client call
2) Singleton service
The singleton service is the ultimate sharable service. When you configure a service as
a singleton, all clients are independently connected to the same single well-known
instance context and implicitly to the same instance inside, regardless of which endpoint
of the service they connect to. The singleton is created exactly once, when the
host is created, and lives forever:it is disposed of only when the host shuts down.
By its very nature, the singleton is shared, and each client should simply create its own proxy or proxies to it.
1) If you are using wsHttpBinding then by default you will get PerSession instancing and you will get one instance per proxy. If you are using BasicHttpBinding then by default you will get PerCall instancing - one instance per request.
2) As Thomas says, singletons are created when the ServiceHost is opened (or you can create them yourself. The singleton will live as long as IIS keeps the AppDomain / worker process alive. You can configure the timeouts that affect this to varying degrees depending on which version of IIS you are using http://www.iis.net/ConfigReference/system.applicationHost/applicationPools/add/recycling

Any recommendations to host a WCF service?

Have a winform application and want to host a WCF service inside it. Do I need to host it in a seperate appdomain? Any recommendations?
You don't need to host it in separate domain but you must decide if you want service request to be processed by UI thread or different thread. It depends on the way you create ServiceHost instance or on ServiceBehavior applied to your service class.
When service is hosted in UI thread it can directly interact with UI but request processing is part of message loop and all service requests are processed by single thread (sequentially). When request is processed no other windows event (including UI events) can be processed = application freezes.
When service is hosted in different thread it behaves as in any other hosting environment but it can't directly interact with UI - you must use delegate invocation.
Ways to enforce service to run in own threads:
Create and open ServiceHost instance before you call Application.Run (start of Windows message loop)
Create and open ServiceHost instance in separate thread
Use [ServiceBehavior(UseSynchronizationContext = false)] on your service implementation
No, you don't have to host it in a separate AppDomain. Just host it. There's nothing terribly special about WinForms in this regard.
What's your app do? Is the service a part of the apps regular functions or a completly seperate logical entity?
If you want to be loading and unload resources (such as assemblies) related to your service without shutting your app down a seperate app domain would make this much easier, but otherwise I don't see much of a reason to complicate things.
Just my 2c. :-)
You can host in Win form but you have to keep it running throughout.
Also suggest you to host in IIS so any type of client avail your service.

Find Endpoint addresses for a service implementation without OperationContext.Current

I have a WCF service in which I would like to do some initialization-type operations based on the configured EndpointAddresses for a few different contracts implemented by the service.
The service can be (and is) hosted from within a few different Service Hosts. There is a console application which creates a service host, a windows service which creates a service host, it lives in an IIS host and I would also really like to be able to use the Visual Studio service host for debugging.
Is there any way to get a reference to the ServiceHostBase which created the instance of the service without being inside a service operation? Or maybe a better (read: trickier) way of figuring out what endpoints the service is servicing?
Let me see if I have this straight: You have a single Service implementation that is exposed from multiple ServiceHosts, and you want to do some different initialization for each servicehost? Or is it for each endpoint exposed?
It sounds to me like there are a few options here, but it depends on exactly what you want to do. If the intialization is per-host, then why not just use your own ServiceHost implementation and do the initialization there instead of the service?.
I ask this particularly because it is not clear from your description what the instance mode of your service is or when you want to run the initialization code itself.
If for whatever reason you can't do that, another option worth exploring could be to do the initialization in a custom IServiceBehavior during ApplyDispatchBehavior(), where you've got access to the service host and the service description.