Simplify Using IOC Container with WCF - 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.

Related

Manual WCF Service Design

First please tell me is this solution structure is good as far as Architecture is concern?
I have XXXX. Business project in center.
XXXX. Contract project has a reference of it.
XXXX. Service project has reference of Contract and Business project.
Now i want my service to be hosted on flexible environments. That's why I want to put custom hosting logic in the Service > Host folder. This project will also have Custom Instance providing facility so that My service classes can be created with some parametric constructor.
Also I need to have different kind of endpoints so I also have a folder for Bindings
These 3 custom things currently suffice my requirement.
Now please guide me with some sample code snippet for Bindings/Host/Instance
I do not know what you mean by
i want my service to be hosted on flexible environments
and
I want to put custom hosting logic in the Service > Host folder
The type of hosting container used depends on the type of project (web, console, windows service, etc) which the service implementation is reference in. This is not something you want to bundle into one project, you should have a different project (or even a different solution) for each of your different service instances.
And this leads to your general solution structure. By placing the contracts as a project in your solution, you are coupling the contract assembly build (and potentially, deployment) to the build and deployment of your solution. The contracts should ideally be in their own solution so that they can be built and managed separately from your service implementation. What if at some time you need to maintain multiple versions of your contracts?
I think your approach to create a generic service which can be anything to anyone is way to complex. You should let WCF take care of this kind of work for you, create a different project at least for each of your service implementations, and defer the bindings management to deploy-time.
Additionally, unless you are writing your own custom bindings code you will not require a folder for bindings.
Bindings can (and should) be defined in configuration when you ship your endpoint, and to some extent, the decision about which transport binding to use should be an administration or management rather than a development concern.

A bit confused about .NET's WCF configuration basics

I'm new to WCF, so I opened up 2 projects: WCF class library and a host console application.
Now, both projects have app.config to store the WCF service configuration settings.
As it seems to me now, and correct me if I'm wrong, I have redundancy in configuring both projects with WCF settings.
How is it done in real world production software ? Does it use separate *.dll library for WCF services, or is it implemented withing the host project (and by that use a single place configuration of it) ?
Thank you .
EliorCohen's answer is correct, but I wanted to expand on a couple of points.
First, your building a WCF class library - library's don't use configuration files on their own. They use the configuration file of the calling application. This is something that I've seen cause a lot of confusion for developers, especially if they create a new class library and they see an App.config file in the project.
Second, with WCF 4 you can actually host a service without specifying anything in the configuration file. The runtime will add default endpoints based on the URI's supplied when you construct the service host.
You can also use set up default bindings and behaviors that will override the normal defaults - for example, if all of your services would be handling large requests, you might want to define a default binding with larger values (by ommitting the name attribute in the Binding configuration).
WCF is wonderful in that it has a lot of options - but that blessing is also a curse at times, especially when you first start working with it.
For more information on default endpoints and stuff, see A Developer's Introduction to Windows Communication Foundation 4.
Note that you'll still need a configuration file for any client apps.
the wcf project you are building represent an implementation of the service.
the configuration need to be on the host of the service (your host app).

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.

Common cache for wcf services launched in different servicehosts

I'm hosting my WCF application with IIS. To serve some methods I need a reference to helper object which is heavily initialized. A good scenario is to initialise it once and put in a cache, then all requests just use the object from cache. How can I do caching?
The easyiest way is to use static field of mywebmethod. IIS creates several ServiceHosts to serve requests. And in every servicehost static fields will be different.
I aso tried using System.Web.HttpRuntime.Cache. Again, I have some independent caches.
To clarify, I need to cache not the result of the request, but some intermediate data needed to process request.
So what can be a solution?
Running diferent services in separate AppDomains gives you crash-protection and some other, security-related benefits. If you are sure you need shared statics, consider using self-hosted servies.
I can think of only one way to achieve this using IIS: implement a ServiceHostFactory, that will return custom ServiceHost that will start and stop multiple ServiceHosts under the hood. But it's waaay too hacky to be a piece of production code )
Update I stumbled upon this today, and this answer looks like a total mess. Different Service host do share one AppDomain if they reside inside the same IIS site, so static fields should be the same for all services.

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.