ssannandeji / Zenject-2019

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

Exception: Multiple instances of SignalBus found #656

Open pilzinho opened 5 years ago

pilzinho commented 5 years ago

Hello!

We have the following error: When loading 3 scenes each with a SceneContext and parented using Contract Names and the SignalBus installed in the first scene we get the following exception when the third scene is loaded:

ZenjectException: Found multiple matches when only one was expected for type 'SignalBus' while building object with type 'SignalBus'. Object graph: SceneKernel DisposableManager SignalBus

The second and third scene each install a component which gets the SignalBus injected. I have created a simple project to reproduce the error. I'm on Windows 10 with Unity 2018.4.3f1 with Zenject 8. To run the project open it in Unity and add 'Zenject-WithSampleGames@v8.0.0.unitypackage ' (the GameSignalsInstaller from the sample game is used in the test project). The main scene is called 'SignalBusIssueScene1' located in the folder 'SignalBusIssue'. I also attached the output log from the build so you can see the whole stack trace of the exception. output_log.txt ZenjectSignalBusIssueProject.zip

MatthieuG9 commented 3 years ago

Hi !

Same issue with

MatthieuG9 commented 3 years ago

I solved my issue by replacing my ProjectContext Installer by another installer in a parent scene.

HedgehogNSK commented 3 years ago

Same here.

This line inside of SignalBusInstaller:

Container.BindInterfacesAndSelfTo<SignalBus>().AsSingle().CopyIntoAllSubContainers();

But this line is cause of the problem in next cases: For example, we have Main, Level, and UI scenes. If we add call of the SignalBusInstaller.Install inside the Main scene installer and set the Main scene as the parent contract of the Level scene context, and then try to set Main and Level as the parent contracts of the UI. As a result we will catch an exception. Because the SignalBus instance will be bound to the Main and Level containers both. So when the SceneKernel of the UI scene try to resolve SignalBus instance, there will be 2 SignalBus instances inside container. And it can't get the unique one.

I haven't found solution yet.


Update. I couldn't find smart solution. Than what I did:

  1. in SignalBusInstaller.cs:
            Container.BindInterfacesAndSelfTo<SignalBus>().AsSingle();//.CopyIntoAllSubContainers();
            Container.BindInterfacesTo<SignalDeclarationAsyncInitializer>().AsSingle();//.CopyIntoAllSubContainers();
  2. Create Project context. Call SignalBusInstaller.Install from installer which is connected to project context. Move all signal declaration to this installer.

Messy... but it works.