Zenject 的 DiContainers 的分层架构
Layered architecture by Zenject's DiContainers
在我的应用程序中,我有三层:
* 数据(实体和数据访问对象)
* 模型(经理)
* 演示文稿(观看次数)
我决定SubContainers
是我的选择。
在根 GameInstaller
中,我创建了每个容器并使用 LayerInstallers 手动安装它们:
public class GameInstaller : MonoInstaller
{
public GameDataLayerInstaller DataLayerInstaller;
public GameModelLayerInstaller ModelLayerInstaller;
public GamePresentationLayerInstaller PresentationLayerInstaller;
public override void InstallBindings()
{
var dataContainer = Container.CreateSubContainer();
dataContainer.Inject(DataLayerInstaller);
DataLayerInstaller.InstallBindings();
var modelContainer = dataContainer.CreateSubContainer();
modelContainer.Inject(ModelLayerInstaller);
ModelLayerInstaller.InstallBindings();
var presentationContainer = modelContainer.CreateSubContainer();
presentationContainer.Inject(PresentationLayerInstaller);
PresentationLayerInstaller.InstallBindings();
}
}
在模型安装程序内部,我将 GameAppManager
添加到图表中。
public class GameModelLayerInstaller : MonoInstaller
{
public GameAppManager GameAppManager;
public override void InstallBindings()
{
Container.BindInstance(GameAppManager);
Container.QueueForInject(GameAppManager);
}
}
在 Presentation-Installer 内部,我将 GameApp 添加到图中。
public class GamePresentationLayerInstaller : MonoInstaller
{
public GameApp GameApp;
public override void InstallBindings()
{
Container.BindInstance(GameApp);
Container.QueueForInject(GameApp);
}
}
然后我尝试通过 GameApp.InjectDependencies(...)
方法解决它:
public class GameApp : MonoBehaviour
{
private GameAppManager _appManager;
[Inject]
public void InjectDependencies(GameAppManager appManager)
{
_appManager = appManager;
}
}
但是 Zenject 抛出这个异常:
ZenjectException: Unable to resolve type 'RsQuest.Game.Model.App.GameAppManager' while building object with type 'RsQuest.Game.Presentation.App.GameApp'.
Object graph:
GameApp
我该如何处理这个案例? GameObjectContext 有更好的方法吗?
我对发生的事情的最佳猜测是 GameApp 被注入了两次。一次通过展示容器,一次通过 SceneContext 容器。默认情况下,场景中的任何 MonoBehaviours 都被假定为属于 SceneContext,除非它们在 GameObjectContext 中。所以你是对的,我认为做你想做的事情的最好方法是使用 GameObjectContext。通常你不需要自己打电话 DiContainer.CreateSubContainer。
如果您在启动时场景中已经有了 MonoBehaviours,您希望在子容器中,那么您可以直接为这些对象添加 GameObjectContext 父变换。或者,如果它们是动态创建的,那么您可以使用 FromSubContainerResolve.ByNewPrefabX 方法之一,作为工厂或直接在场景容器上使用。
在我的应用程序中,我有三层: * 数据(实体和数据访问对象) * 模型(经理) * 演示文稿(观看次数)
我决定SubContainers
是我的选择。
在根 GameInstaller
中,我创建了每个容器并使用 LayerInstallers 手动安装它们:
public class GameInstaller : MonoInstaller
{
public GameDataLayerInstaller DataLayerInstaller;
public GameModelLayerInstaller ModelLayerInstaller;
public GamePresentationLayerInstaller PresentationLayerInstaller;
public override void InstallBindings()
{
var dataContainer = Container.CreateSubContainer();
dataContainer.Inject(DataLayerInstaller);
DataLayerInstaller.InstallBindings();
var modelContainer = dataContainer.CreateSubContainer();
modelContainer.Inject(ModelLayerInstaller);
ModelLayerInstaller.InstallBindings();
var presentationContainer = modelContainer.CreateSubContainer();
presentationContainer.Inject(PresentationLayerInstaller);
PresentationLayerInstaller.InstallBindings();
}
}
在模型安装程序内部,我将 GameAppManager
添加到图表中。
public class GameModelLayerInstaller : MonoInstaller
{
public GameAppManager GameAppManager;
public override void InstallBindings()
{
Container.BindInstance(GameAppManager);
Container.QueueForInject(GameAppManager);
}
}
在 Presentation-Installer 内部,我将 GameApp 添加到图中。
public class GamePresentationLayerInstaller : MonoInstaller
{
public GameApp GameApp;
public override void InstallBindings()
{
Container.BindInstance(GameApp);
Container.QueueForInject(GameApp);
}
}
然后我尝试通过 GameApp.InjectDependencies(...)
方法解决它:
public class GameApp : MonoBehaviour
{
private GameAppManager _appManager;
[Inject]
public void InjectDependencies(GameAppManager appManager)
{
_appManager = appManager;
}
}
但是 Zenject 抛出这个异常:
ZenjectException: Unable to resolve type 'RsQuest.Game.Model.App.GameAppManager' while building object with type 'RsQuest.Game.Presentation.App.GameApp'.
Object graph:
GameApp
我该如何处理这个案例? GameObjectContext 有更好的方法吗?
我对发生的事情的最佳猜测是 GameApp 被注入了两次。一次通过展示容器,一次通过 SceneContext 容器。默认情况下,场景中的任何 MonoBehaviours 都被假定为属于 SceneContext,除非它们在 GameObjectContext 中。所以你是对的,我认为做你想做的事情的最好方法是使用 GameObjectContext。通常你不需要自己打电话 DiContainer.CreateSubContainer。
如果您在启动时场景中已经有了 MonoBehaviours,您希望在子容器中,那么您可以直接为这些对象添加 GameObjectContext 父变换。或者,如果它们是动态创建的,那么您可以使用 FromSubContainerResolve.ByNewPrefabX 方法之一,作为工厂或直接在场景容器上使用。