Swinject: Recursive `resolve()` deadlocks with `synchronize()`-d resolver

I see that internally the SynchronizedResolver class uses container’s SpinLock (which is NSLock) to make locks. Can we change the NSLock to NSRecursiveLock here?

BTW, here’s my use case (simplified of course - I do have concurrency):

public class A {
    private let b: B
    init(with r: Resolver) {
        b = r.resolve(B.self)    // this dead locks!
    }
}
private class B {}

let c = Container()
let threadSafeResolver = c.synchronize()

c.register(A.self, factory: { _ in return A(with: threadSafeResolver) })
c.register(B.self, factory: { _ in return B() })

threadSafeResolver.resolve(A.self)

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 2
  • Comments: 30 (9 by maintainers)

Commits related to this issue

Most upvoted comments

Hello. Any updates on that?

Hello,

so quite some time passed since the issue was created but the problem still remains.

I understand the idea that you should not use resolve() in such a way, but you should consider that in a legacy code project it is pretty hard to introduce a library like Swinject in a clean way right from the start. To do that I need to refactor a lot of code.

I run into the same problem as OP and a change from NSLock() to NSRecursiveLock() solve my problem.