WCF Service - Single Instance - Static constructor - wcf

Just want to confirm my understanding is correct. If I use Single instance mode for a service:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
and this service calls a class from another asssembly which has a static constructor, that constructor is only called the first time ther service is called? The constructor I am talking about sets up a fair number of AutoMapper maps, and I only want this overhead the first time the service is called.
Taking this further, If I have two different services, and they both us the shared class, am I correct that the static constructor is still only called once?
Best
Ray

There is no connection between InstanceContextMode and how many times static constructor is fired. Static constructor is called once per Application Domain. So if your services are hosted within one Application Domain then your constructor will be called once.
As far as I understand you use the contructor to register AutoMapper configuration... To me it is not a good approach. Assuming your services are hosted on IIS you would better create a Global.asax file and then run you mapping registration code in Application_Start method. Of cource you can wrap it in some static method first.
Hope it helps!

Related

WCF 4.0 Instance Management inside of Instanced Service Objects?

I have a WCF service using the per-instance call pattern. It is self-hosted, not using IIS at all.
The service class instances another class with the pattern
var myfoo = new Foo().GetResultFromDictionary(something);
The Foo class reads from an embedded resource, does some lookups, and returns an object of Bar that the service class then uses.
Creating a new instance for a single call on Foo() seems like a waste. Once it loads, all instances of the service should be able to make the call.
Does anyone have design recommendations for this? I do not want to fall into the trap of over-optimizing and pre-optimizing if there is no problem here (eg if .NET Framework will take care of instance management for Foo), but I'm not sure.
All ideas appreciated, thanks.
I am going to work through the System.Runtime.Caching bits, creating a static class that inserts into MemoryCache.Default when the static "constructor" is called, and reading from the cache on all subsequent calls.

Obtain an reference to a wcf service

I have a wcf service singleton type, and in the same application an ASP page that uses a service-specific function.
As I can get a reference to the service instance created, not to run twice the manufacturer's service?
My service is published on IIS
I'm guessing you are saying that you have a service that is supposed to be a singleton and because you're in the same AppDomain you can simply create an instance as well.
If you own the service code you can make it a singleton using the Singleton Pattern (there are a number of ways to do that in .NET and Jon Skeet has a list of them here).
Then you need to deal with how does WCF get hold of the instance? In that case there are two options:
Use a ServiceHostFactory and hand the instance to the ServiceHost you create
Implement IInstanceProvider and plumb that in
If you don't control the service class then there is nothing you can do to prevent people creating instances but you can wrap the class in your own singleton and stipulate access must only be via the singleton so it is less likely that someone will create a second instance

WCF and Ninject

within our per-session WCF services hosted in ISS, we would like to use Ninject to IOC different data access component through the interface.
Where would be the best place to declare the binding once? is it in Application_Start of Global.asax?
If it is, how could I obtain the instance through the inferface from Ninject?
I know in StructureMap, we can call something like ObjectFactory.GetInstance()?
What is the equivalent in Ninject?
Thanks
I assume you have looked at the official WCF extension? I usually define my own service factory (referenced in the .SVC file) and reference my Ninject module from there.
As for getting an instance from an interface (i.e. the opposite of having it injected), you do so via the kernel. (You can always have an instance of IKernel injected into any of your classes by adding it to your constructor.) Once you have it, you just use:
kernel.Get<IYourInterface>();

References for what the lifecycle is for a WCF service?

Say I have a simple WCF application that the client calls in order to get a number. There's not much processing in it and the service contract is attributed as SessionMode=SessionMode.NotAllowed.
When is the constructor called? When is the object destructed? Is a constructor called per request?
Are there any reference documents or resources that have this information? I can't seem to find it.
WCF is hosted by IIS, and thus subject to its lifetime rules. A service class, by itself, will probably be created and destroyed as necessary within the app; the class will be constructed upon receipt of a request, the method called, and the result returned, after which the object will leave scope and be disposed/finalized.
However, the project containing your service looks like an ordinary ActiveServer.NET web app to IIS (check out the Global.asax file that should be in it; it contains a class of type HttpApplication, and represents the entry point for the app that IIS can use to control it), and IIS will maintain a "pool" of these applications to handle requests from multiple clients. As long as requests keep coming in, and IIS doesn't decide an app has gotten "stale" and refreshes it or the entire pool, the application will continue to run. So, any static classes you declare, for instance your singleton IoC container, or anything you add to a derived HttpApplication class that you use as your child type, will remain in memory until the app is recycled.

NHibernate Session gets disposed off on each wcf service method call

I am using Wcf in Sharp Architecture. I have configured my project following northwind sample using WcfSessionStorage etc. I have a method in the wcf service that gets a list of business object using Repository<>.GetAll(). I am testing the service method using WcfTestClient. When the method is called the very first time, everything works fine. However on the subsequent call, I get the following exception on the Repository<>.GetAll() method
[System.ObjectDisposedException]
Session is closed!
Object name: 'ISession'
It seems like the NHibernate session gets disposed after each call. I have got around this problem by decorating my service with the following attribute
[ServiceBehavior( InstanceContextMode = InstanceContextMode.PerCall )]
public class WcfService : IWcfService
{
}
However this means, an instance of the service will be created on each call that in turn will create a new nhibernate session etc. In my scenario there is no need of creating a new service instance per call and I think its an expensive process and not the right solution. I would like to know what is the best practice in my scenario and how to get this thing work with creating a new service instace per call.
Thanks
Nabeel
The easiest way is to create a new instance every time and it's not an expensive process, because creating a new object in .NET is like 0.00000000000000001 second (I read that on Ayande's blog or somewhere).
I use Autofac DI in my projects and I usually make ISession as container scoped (one per request). And then every class that uses (directly or indirectly) ISession has to be container scoped or lower (factory scoped == every class usage get's a new instance). If a class that uses ISession is higer scoped (session scoped == singleton) you'll run into problems that you currently have.
If your service is singleton service:
At first run the service is created, this service uses ISession, which should be container scoped, and it is on the first run.
The next request to service (service is now created) has still a reference to created ISession (which was closed on previous end request), so now it's closed.
I don't recomend using the same ISession that you'll open/close (it's not recomended in the NHibernate documentation), just use container scoped (I do and I don't have any performance issues), or you should create ISession manually in every method in your service like:
using(ISession s = ISessionFactory.OpenSession())
using(ITransaction t = .....)
....
But that isn't nice at all...
Please take a look at my answer to my own similar question: WCF/S#arpArch: underlying ISession is closed after the first call within a request.
#dmonlord is right that the creation of additional session instances within the same request is very cheap in this case.