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 方法之一,作为工厂或直接在场景容器上使用。