如何解决FromNewComponentSibling复用实例时的循环依赖问题
问题描述
我当前的绑定代码如下:
Container.Bind<ICompanion>() .To<RouMainMenuPresenterCompanion>() .FromNewComponentSibling() .WhenInjectedInto<MainMenuPresenter>(); Container.Bind<RouMainMenuPresenterCompanion>() .FromResolve();
我希望达到的效果是:在MainMenuPresenter中注入的ICompanion类型实例(通过FromNewComponentSibling()创建的RouMainMenuPresenterCompanion),后续能作为RouMainMenuPresenterCompanion类型被任何解析器复用,但上面的代码出现了循环依赖,请问该如何解决?
嘿,这个问题我之前做项目时也踩过坑!核心问题在于你当前的绑定逻辑形成了循环链:FromResolve()会让容器尝试解析RouMainMenuPresenterCompanion,但这个类型又被绑定到了ICompanion的FromNewComponentSibling规则上,而后者又依赖于MainMenuPresenter的上下文,绕来绕去就卡死了。
给你几个实用的解决思路:
思路1:让同一个实例同时注册两种类型(最推荐)
你可以直接修改第一个绑定,让创建的RouMainMenuPresenterCompanion实例同时被容器记录为自身类型,这样就不需要单独的FromResolve()绑定了:
Container.Bind<ICompanion>() .To<RouMainMenuPresenterCompanion>() .FromNewComponentSibling() .WhenInjectedInto<MainMenuPresenter>() .AsSelf(); // 关键:让这个实例同时注册为RouMainMenuPresenterCompanion类型
这样操作后,当MainMenuPresenter注入ICompanion时,容器会创建RouMainMenuPresenterCompanion实例,同时这个实例会被容器标记为可复用的RouMainMenuPresenterCompanion类型。后续任何在MainMenuPresenter上下文里解析RouMainMenuPresenterCompanion的地方,都会拿到同一个实例。
思路2:用工厂模式手动控制实例流程
如果上面的方法不符合你的业务场景,你可以用工厂来手动创建实例并完成双类型绑定:
Container.BindFactory<MainMenuPresenter, RouMainMenuPresenterCompanion>( (container, presenter) => { // 创建同级组件实例 var companion = container.InstantiateComponentSibling<RouMainMenuPresenterCompanion>(presenter.gameObject); // 手动把这个实例绑定到容器,供后续复用 container.Bind<RouMainMenuPresenterCompanion>().FromInstance(companion).WhenInjectedInto<MainMenuPresenter>(); return companion; }); // 把ICompanion绑定到这个工厂 Container.Bind<ICompanion>() .ToFactory<MainMenuPresenter, RouMainMenuPresenterCompanion>() .WhenInjectedInto<MainMenuPresenter>();
这种方式灵活性更高,适合需要自定义实例初始化逻辑的场景,但代码量会稍多一些。
思路3:调整绑定顺序,复用已创建组件
如果你的RouMainMenuPresenterCompanion本身就是MainMenuPresenter的同级组件,也可以先确保组件被创建,再绑定ICompanion:
// 先创建并绑定RouMainMenuPresenterCompanion Container.Bind<RouMainMenuPresenterCompanion>() .FromNewComponentSibling() .WhenInjectedInto<MainMenuPresenter>(); // 再绑定ICompanion到已存在的组件实例 Container.Bind<ICompanion>() .To<RouMainMenuPresenterCompanion>() .FromExistingComponent() .WhenInjectedInto<MainMenuPresenter>();
这种方式避免了循环解析的问题,适合组件需要提前初始化的场景。
内容的提问来源于stack exchange,提问作者Alexandr

