modesttree / Zenject

Dependency Injection Framework for Unity3D

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Async Support for bindings

altunsercan opened this issue · comments

Is your feature request related to a problem? Please describe.
An often requested feature for Extenject is to support Async operations. This mostly comes up in async only apis like Addressable implementation in Unity. However due to nature of dependency injection, the injection happens once per target object and bindings won't update again. This means that if an async resource is not available at the moment of injection, it won't update later on. In order for Extenject to support async apis there needs to be an async support for bindings.

Describe the solution you'd like
This feature request proposes to introduce a special binding rule, similar to LazyInject<Foo> implementation. With LazyInject<Foo> a token object is injected instead of contract type Foo. This allows implementer to delay resolving the binding at a later stage. Binding resolves only after the first time implementer asks for lazyFoo.Value parameter. However, LazyInject does not track any async processes and you cannot ask questions like lazyFoo.HasValue to determine if a binding is available.

With an AsyncInject implementation we can provide an async friendly binding alternative. Implementers can use properties like asyncFoo.HasResult to check if async binding is completed, then ask for asyncFoo.Result to get the resulting value. There can also be events to listen to for Complete, Cancelled etc.

Of course for AsyncInject to work there should be a binding counterpart. As a simple proof of concept implementation, this feature can start with something with general use case like Container.Bind<Foo>().FromAsyncMethod(injectionContext=> x.AsyncMethod ) where the value is bound to an AsyncProvider. If implementer wants to trigger async method, they can add .NonLazy() at the end of the binding statement and instantiate the object immediately like other NonLazy bindings.

Also with the implementation we can provide code samples for preloading addressables or calling server endpoints with async methods to show some common use cases.

Describe alternatives you've considered
I have previously implemented an AddressableLoading repository to provide example on how to support Addressables with Extenject. It used kernel replacement to preload addressables before running Initialize or Tick on created objects. However this implementation was simply to provide example for my use case. It is neither flexable nor cover all possible use cases for addressables (not even for my own liking).

Lately we added DecoratableKernel to make this implementation simpler that shown in above repository. Decorating kernel to async load addressables still comes with the assumption that addressables must be loaded pre initialize calls. This is an unnecessary assumption for other Async use cases.

Proposed solution, while more basic, would cover more use cases.

Additional context
This is not an exhaustive async feature set. There could be many other async operations in Unity that might be supported later on. Also there could be addressable specific FromAddressableX binding rules in the future.