Многоуровневая архитектура от DiContainers от Zenject

В моем приложении у меня есть три слоя: * Данные (сущности и объекты доступа к данным) * Модель (менеджеры) * Презентация (представления)

образ

Я решил что 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();
    }
}

Внутри Model-Installer добавляю 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?

1 ответ

Решение

Мое лучшее предположение о том, что происходит - GameApp вводится дважды. Один раз по контейнеру представления, и один раз по контейнеру SceneContext. По умолчанию предполагается, что любые MonoBehaviours в сцене принадлежат SceneContext, если они не находятся внутри GameObjectContext. Так что вы правы, я думаю, что лучший способ сделать то, что вы пытаетесь сделать, это использовать GameObjectContext. Обычно вам не нужно вызывать DiContainer.CreateSubContainer самостоятельно.

Если у вас уже есть MonoBehaviours в сцене при запуске, который вы хотите разместить внутри подконтейнера, то вы можете напрямую добавить родительское преобразование GameObjectContext для этих объектов. Или, если они создаются динамически, вы можете использовать один из методов FromSubContainerResolve.ByNewPrefabX либо в качестве фабрики, либо непосредственно в контейнере сцены.

Другие вопросы по тегам