JasperFx / lamar

Fast Inversion of Control Tool and Successor to StructureMap
https://jasperfx.github.io/lamar
MIT License
566 stars 117 forks source link

Lamar creates instance duplicates when target class is IDisposable #215

Closed kutensky closed 4 years ago

kutensky commented 4 years ago

I faced the problem that when I have many requests to the same MVC controller, sometimes I have the error "A single instance of controller '...' cannot be used to handle multiple requests". After deeper investigation I found out that when we request some concrete class from Lamar container in parallel and this class implements IDisposable interface, sometimes it will return same instances. I attached the unit test that demonstrates this behavior. After deeper investigation I found out that when I call "GetInstance" on Container, it generates resolver with next code:

(inline_myObject = new MyObject())
(myObject2 = new MyObject2(inline_myObject))
scope.get_Disposables().Add(myObject2)
myObject2

Meanwhile if MyObject2 doesn't implement "IDisposable", it will generate next code:

(inline_myObject = new MyObject())
new MyObject2(inline_myObject)

And in this case there won't be any duplicates. So obviously problem is in the fact that if class implements "IDisposable", we don't just return constructor invocation result, we put it in variable and then return. I suppose this variable might be somehow reused between threads.

ParallelTest.txt

jeremydmiller commented 4 years ago

@kutensky We've had other issues where the variables seem to be shared in heavy multi-threading. I've got your repro steps applied, reproduced the error, and I'm gonna tweak the expression stuff.

jeremydmiller commented 4 years ago

@kutensky Got it, and it's related I'm pretty sure to using Expression.Block().