Layered architecture by Zenject's DiContainers

左心房为你撑大大i 提交于 2019-12-11 14:43:58

问题


In my application I have three layers: * Data (Entities and Data Access Objects) * Model (Managers) * Presentation (Views)

I decided that SubContainers is my choice.

In the root GameInstaller I create every container and manually install them with 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();
    }
}

Inside of Model-Installer I add GameAppManager into the graph.

public class GameModelLayerInstaller : MonoInstaller
{

    public GameAppManager GameAppManager;

    public override void InstallBindings()
    {
        Container.BindInstance(GameAppManager);
        Container.QueueForInject(GameAppManager);
    }
}

Inside of Presentation-Installer I add GameApp into the graph.

public class GamePresentationLayerInstaller : MonoInstaller
{

    public GameApp GameApp;

    public override void InstallBindings()
    {
        Container.BindInstance(GameApp);
        Container.QueueForInject(GameApp);
    }
}

Then I trying to resolve it from GameApp.InjectDependencies(...) method:

public class GameApp : MonoBehaviour
{

    private GameAppManager _appManager;
    [Inject]
    public void InjectDependencies(GameAppManager appManager)
    {
        _appManager = appManager;
    }
}

But Zenject throws this exception:

ZenjectException: Unable to resolve type 'RsQuest.Game.Model.App.GameAppManager' while building object with type 'RsQuest.Game.Presentation.App.GameApp'. 
Object graph:
GameApp

How can I manage this case? Is there any better way with GameObjectContext?


回答1:


My best guess for what's happening is GameApp is being injected twice. Once by by presentation container, and once by the SceneContext container. By default, any MonoBehaviours in the scene are assumed to belong to the SceneContext unless they are inside a GameObjectContext. So you're right, I think the best way to do what you're attempting to do is to use GameObjectContext. Usually you shouldn't need to ever call DiContainer.CreateSubContainer yourself.

If you've already got MonoBehaviours in the scene at startup that you want to be inside a subcontainer, then you can directly add a GameObjectContext parent transform for these objects. Or, if they are created dynamically, then you can use one of the FromSubContainerResolve.ByNewPrefabX methods, either as a factory or directly on the scene container.



来源:https://stackoverflow.com/questions/46932959/layered-architecture-by-zenjects-dicontainers

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!