ssannandeji / Zenject-2019

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

ZenjectException occured when omit scope. #504

Open monry opened 6 years ago

monry commented 6 years ago

What

Detail

Sample Code

https://gist.github.com/monry/7aeebe9fce37fb7884d37086bd6e4e16

Log

[15:41:33:381] ZenjectException: Assert hit! Scope must be set for the previous binding!  Please either specify AsTransient, AsCached, or AsSingle. Last binding: Contract: Sample.IFoo, Identifier: NULL 
ModestTree.Assert.That (System.Boolean condition, System.String message, System.Object p1, System.Object p2, System.Object p3) (at Assets/Modules/umm@zenject/Zenject/Source/Internal/Assert.cs:358)
Zenject.ProviderBindingFinalizer.GetScope () (at Assets/Modules/umm@zenject/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs:32)
Zenject.ScopableBindingFinalizer.FinalizeBindingConcrete (Zenject.DiContainer container, System.Collections.Generic.List`1[T] concreteTypes) (at Assets/Modules/umm@zenject/Zenject/Source/Binding/Finalizers/ScopableBindingFinalizer.cs:39)
Zenject.ScopableBindingFinalizer.OnFinalizeBinding (Zenject.DiContainer container) (at Assets/Modules/umm@zenject/Zenject/Source/Binding/Finalizers/ScopableBindingFinalizer.cs:27)
Zenject.ProviderBindingFinalizer.FinalizeBinding (Zenject.DiContainer container) (at Assets/Modules/umm@zenject/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs:54)
Rethrow as ZenjectException: Error while finalizing previous binding! Contract: Sample.IFoo, Identifier: NULL
Zenject.ProviderBindingFinalizer.FinalizeBinding (Zenject.DiContainer container) (at Assets/Modules/umm@zenject/Zenject/Source/Binding/Finalizers/ProviderBindingFinalizer.cs:58)
Zenject.BindFinalizerWrapper.FinalizeBinding (Zenject.DiContainer container) (at Assets/Modules/umm@zenject/Zenject/Source/Binding/Finalizers/BindFinalizerWrapper.cs:41)
Zenject.DiContainer.FinalizeBinding (Zenject.IBindingFinalizer binding) (at Assets/Modules/umm@zenject/Zenject/Source/Main/DiContainer.cs:2478)
Zenject.DiContainer.FlushBindings () (at Assets/Modules/umm@zenject/Zenject/Source/Main/DiContainer.cs:2462)
Zenject.DiContainer.StartBinding (System.String errorContext, System.Boolean flush) (at Assets/Modules/umm@zenject/Zenject/Source/Main/DiContainer.cs:2493)
Zenject.DiContainer.Bind[TContract] () (at Assets/Modules/umm@zenject/Zenject/Source/Main/DiContainer.cs:2527)
Sample.SampleInstaller.InstallBindings () (at Assets/Scripts/Application/Installer/Mono/SampleInstaller.cs:18)
Zenject.Context.InstallInstallers (System.Collections.Generic.List`1[T] normalInstallers, System.Collections.Generic.List`1[T] normalInstallerTypes, System.Collections.Generic.List`1[T] scriptableObjectInstallers, System.Collections.Generic.List`1[T] installers, System.Collections.Generic.List`1[T] installerPrefabs) (at Assets/Modules/umm@zenject/Zenject/Source/Install/Contexts/Context.cs:195)
Zenject.Context.InstallInstallers () (at Assets/Modules/umm@zenject/Zenject/Source/Install/Contexts/Context.cs:136)
Zenject.SceneContext.InstallBindings (System.Collections.Generic.List`1[T] injectableMonoBehaviours) (at Assets/Modules/umm@zenject/Zenject/Source/Install/Contexts/SceneContext.cs:326)
Zenject.SceneContext.Install () (at Assets/Modules/umm@zenject/Zenject/Source/Install/Contexts/SceneContext.cs:260)
Zenject.SceneContext.RunInternal () (at Assets/Modules/umm@zenject/Zenject/Source/Install/Contexts/SceneContext.cs:130)
Zenject.RunnableContext.Run () (at Assets/Modules/umm@zenject/Zenject/Source/Install/Contexts/RunnableContext.cs:36)
Zenject.RunnableContext.Initialize () (at Assets/Modules/umm@zenject/Zenject/Source/Install/Contexts/RunnableContext.cs:22)
Zenject.SceneContext.Awake () (at Assets/Modules/umm@zenject/Zenject/Source/Install/Contexts/SceneContext.cs:106)

Version

svermeulen commented 6 years ago

This is intentional, to avoid issues that often occur when scope is omitted. In many cases (most cases) transient is not intended. We could add a setting in ZenjectSettings to relax this constraint however. Would that be useful?

monry commented 6 years ago

thank you for your answer! I will re-review the design of my program. If it is intentional, I think expansion of setting is unnecessary.

svermeulen commented 6 years ago

In those cases where you get that error, if you intend for it to be transient, you need to explicitly add the AsTransient call. The docs are still correct that it's the default, but some bind types require that the scope be chosen explicitly. For example, FromMethod and FromResolve do not require an explicit scope to be chosen since AsTransient is a much safer assumption in those cases

monry commented 6 years ago

I see! I understood it very well. Thank you for answering politely and quickly!

Is there a list of binding types where scope setting is required somewhere?