hadashiA / VContainer

The extra fast, minimum code size, GC-free DI (Dependency Injection) library running on Unity Game Engine.
https://vcontainer.hadashikick.jp
MIT License
1.96k stars 172 forks source link

[Question] Why VContainer allows to create 2 Singleton instances #556

Closed vangogih closed 1 year ago

vangogih commented 1 year ago

Hi @hadashiA ,

According to the test case CreateScopeWithRegisterSingleton (link) lines 152 and 156 we can create multiple Singleton instances of one type.

It means: if we create a new child scope A which is derived from scope B (scope A is a child of scope B) and Register the same Singleton types on each scope Vcontainer won't throw any exception and will create a new instance for child scope.

I found this behaviour counterintuitive and want to know why it works this way?

Singleton means - one instance per scope. And in case where B derives from A the scope of A and B can't have two Singleton instances of the same type.

Why we can't just return the root dependency instead of creating a new instance for child scope 🤯

hadashiA commented 1 year ago

Yeah. there are some things that are counter-intuitive. Agreed.

Basically, if type Foo is registered as a singleton in the parent container, there is no need to register it in the child container. In this case, retrieving the type Foo from the child container returns a reference to the parent container.

The problem is the behavior when the same implementation type is registered for both parent and child. In the first version, this was an error.

Perhaps I changed this behavior in the process following reason.

For example, suppose there are three nested scopes, A - B - C. (C is a child of B. B is a child of A.) In the first version, there were only two ways to control this: either create a common Singleton for A , B, and C, or each of A, B, and C would have its own instance. But for some reason, I wanted to refer to a common instance for A, B, but override it with a different implementation for C. Neither Singleton , nor Scoped, could meet this requirement. So I made it controllable, on a per-container basis, whether to inherit the parent's reference. To be honest, this might have been a mistake. But it might be a bit difficult to change it now.