Bug of the Day
Something -a bug- happened today that made feel like weeping.
One of those nasty bugs that when you catch it, make's you scream like you have won a war.
I'm working on a Project that I was not involved on it's basic definition. And in cases like that some hidden stuff always pop out.
Based on a DDD approach this project has a module entirely delivered by Services, which are IoC'ed with Windsor on it's clients. So far no big deal.
But last night, our QA team was validation a particular routine which was giving lot of Developers headaches.
When I was presented to the the Bug I started digging on this project's foundation.
The maddening piece of code was something like that:
foreach(ScheduledItem item in items) {
IoC.resolve<IClass>().Do(item.stuff);
}
The problem was that with every Iteration I received an error. Random.
Sometimes it was and PL/SQL error, sometime a null reference error, sometimes neither.
I got stuck with it for some hours.
Just when I thought that was closing on becoming crazier, my salvation came in form of another error.
System.ArgumentException: An entry with the same key already exists.
Hell, how I loved watching this. Haven't been so happy in seeing and error message in sometime. At least, knowing some Internals of the .Do() method, I could elaborate on what was happening.
well, to make a long story short, my issue was that when adding the components on Windsor container, all services were being injected with a Binsor script adding all of then with:
AddComponentWithLifestyle("Class", typeof(Class),IClass, LifestyleType.Singleton) ;
Dang. Every second time IoC.resolve<IClass>().Do(item.stuff) was called, with all-internal-fields-populated I got an error.
It turns out that that's the 'One Service' which has private fields outside the Service's Operation and those fields were never reset on the new method's call.
The error was random because the behavior of the method depend's on the item passed as parameter.
After that, I changed the LifeStyle to LifestyleType.Transient, which generates a new instance (no worries on performance here, it's an batch schedule operation) every call, and everything went fine.
I felt ok after that, but it was one of those moments when one thinks:
- "if I was involved from the beginning at least I would know where to look at".
Sad, but true.