我有一个统一+ Zenject设置,它有一个具有一些全局依赖项的ProjectInstaller
,这些依赖关系遵循一个“模态”接口,例如,
public class ProjectInstaller : MonoInstaller {
public override void InstallBindings() {
Container.Bind<ModalManager>().AsSingle();
Container.Bind<Modal>().To<DialogManager>().AsSingle();
}
}
有些模型只与某些场景相关,所以我将这些绑定在SceneInstaller
中。
public class SceneInstaller : MonoInstaller {
public override void InstallBindings() {
Container.BindInterfacesAndSelfTo<InventoryManager>()
.FromComponentInNewPrefab(InventoryPrefab)
.AsSingle()
}
}
我想从在项目范围内定义的单个管理所有的ModalManager
。所以它有一个List<Modal>
绑定:
public class ModalManager : MonoBehaviour {
[Inject]
protected List<Modal> _modals;
}
当我运行它时,ModalManager
只得到一个单一的模式:在项目范围中定义的模式。据我理解,SceneContext
是ProjectContext
的子容器。因此,我应该能够使用FromSubContainerResolve
在ProjectInstaller
中绑定子场景中的项,也许可以添加如下一行:
// ProjectInstaller.cs
public override void InstallBindings() {
// ...
Container.Bind<Modal>().To<InventoryManager>().FromSubContainerResolve();
}
但是,我不确定在这种情况下,哪种FromSubContainerResolve
方法是有意义的。它们似乎都与带有游戏对象上下文的预制板相关,而不是在ProjectContext
内部使用。
这个用例有意义吗?有没有更简单或更好的方法?
发布于 2022-02-04 17:35:50
问题是,ModalManager
只能注入直接添加到ProjectContext中的依赖项。对于这类问题,我建议使用以下模式:
public interface IModal
{
}
public class ModalManager
{
private readonly List<IModal> _modals = new List<IModal>();
public IReadOnlyList<IModal> Modals
{
get { return _modals; }
}
public void AddModal(IModal modal)
{
_modals.Add(modal);
}
public bool RemoveModal(IModal modal)
{
return _modals.Remove(modal);
}
}
public class ModalRegisterHandler : IInitializable, IDisposable
{
private readonly List<IModal> _modals;
private readonly ModalManager _modalManager;
public ModalRegisterHandler(
// We need to use InjectSources.Local here, otherwise we will
// add any project context modals again in each scene
[Inject(Source = InjectSources.Local)]
List<IModal> modals, ModalManager modalManager)
{
_modals = modals;
_modalManager = modalManager;
}
public void Initialize()
{
foreach (var modal in _modals)
{
_modalManager.AddModal(modal);
}
}
public void Dispose()
{
// We don't want ModalManager to retain references to Modals defined in unloaded scenes
// (dispose is executed on scene unload)
foreach (var modal in _modals)
{
_modalManager.RemoveModal(modal);
}
}
}
public class SceneInstaller : MonoInstaller
{
public override void InstallBindings()
{
Container.Bind<IModal>().To<FooModal>();
Container.Bind<IModal>().To<BarModal>();
}
}
public class ProjectInstaller : MonoInstaller
{
public override void InstallBindings()
{
// We use CopyIntoDirectSubContainers so that ModalRegisterHandler gets automatically added to every
// scene context
Container.BindInterfacesTo<ModalRegisterHandler>().AsSingle().CopyIntoDirectSubContainers();
Container.Bind<ModalManager>().AsSingle();
Container.Bind<IModal>().To<QuxModal>();
Container.Bind<IModal>().To<FizzModal>();
}
}
https://stackoverflow.com/questions/70989976
复制相似问题