ssannandeji / Zenject-2019

Dependency Injection Framework for Unity3D
MIT License
2.53k stars 363 forks source link

FromComponentInNewPrefab(...).AsSingle() does not maintain a singleton instance - creates multiple #596

Closed henriqueranj closed 5 years ago

henriqueranj commented 5 years ago

Hello,

I have a project that used Zenject v5.4.0 and when using FromComponentInNewPrefab(...).AsSingle() multiple times in one installer it maintains only one instance of the given Prefab in the Scene, while binding all required components from that instantiated prefab:

Container.Bind<PuppetView>().FromComponentInNewPrefab(CharacterPrefab).AsSingle().NonLazy();
Container.Bind<FsmEventDispatcher>().FromComponentInNewPrefab(CharacterPrefab).AsSingle().NonLazy();
Container.Bind<PuppetAudioHandler>().FromComponentInNewPrefab(CharacterPrefab).AsSingle().NonLazy();
Container.Bind<Animator>().FromComponentInNewPrefab(CharacterPrefab).AsSingle().WhenInjectedInto<PuppetAudioHandler>();

However, when using v7.3.1 it is generating multiple instances of the prefab, even though it is stated to be AsSingle(). Was this an intended change? I do not seem to find any clear reference to this, so I must assume it is a bug.

svermeulen commented 5 years ago

Yes unfortunately there was a breaking change in Zenject 6 regarding AsSingle that caused this. I would have at least expected an error message though. You can see the upgrade notes which explain it here. Basically using AsSingle across bind statements had too much implementation costs and error edge cases so it was dropped.

One way that might work is something like:

Container.Bind(typeof(PuppetView), typeof(FsmEventDispatcher), typeof(PuppetAudioHandler)).FromComponentInNewPrefab(CharacterPrefab).AsSingle().NonLazy();

Container.Bind<Animator>().FromResolveGetter<PuppetView>(x => x.Animator).WhenInjectedInto<PuppetAudioHandler>();

Or maybe putting the character prefab in a subcontainer