Как связать список не-MonoBehaviour объектов с классом менеджера, используя Zenject - PullRequest
1 голос
/ 19 января 2020

Я использую Zenject для внедрения зависимостей в моей игре и нахожусь в тупике.

Позвольте мне описать мою текущую настройку:

У меня есть несколько персонажей с собственными GameObjectContext и CharacterInstaller, ответственный за введение CharacterController в CharacterPresenter.

public class CharacterInstaller : MonoInstaller<CharacterInstaller>
{
    public override void InstallBindings()
    {
        Container.BindInterfacesAndSelfTo<CharacterInstaller>().AsSingle().NonLazy();
    }
}
// PLAIN C# class
public class CharacterController : <some_interfaces>
{
    public void Foo()
    {
        // ...
    }
}
public class CharacterPresenter : MonoBehaviour
{
    private CharacterController characterController;

    [Inject]
    public void InjectDependencies( CharacterController characterController )
    {
        this.characterController = characterController;
    }

    public void Foo() => characterController.Foo();
}

То, что я хотел бы сделать, это также внедрить все экземпляры CharacterController класс в класс "Manager" с использованием Привязки к списку . Этот менеджер не является родителем моих персонажей, и мне могут понадобиться несколько менеджеров.

public class CharactersManager
{
    private List<Character> characters;

    public CharactersManager( List<Character> characters)
    {
        this.characters = characters;
    }

    public void MakeCharactersDoSomething()
    {
        foreach ( Character character in characters)
            character.Foo();
    }
}

Более близкие вещи, которые я нашел для решения моей проблемы:

• Присоединение компонента ZenjectBinding своему персонажу и укажите нужный мне контекст.
→ Не может работать, потому что CharacterController - это простой C# класс, а ZenjectBinding только связывает компоненты

• Объявите Context в CharacterInstaller и вызов OtherContext.Container.Bind...
→ Сбой, потому что OtherContext.Container является нулевым

• Вызов Container.Bind<CharacterController>().FromComponentsInHierarchy() в установщике моего менеджера
→ Не работает, потому что CharacterController не является компонентом

• Использование фабрики
→ Я не могу ее использовать, поскольку мои объекты должны быть размещены во время редактирования в редакторе

• Использование Container.ParentContainers в моем CharacterInstaller
→ Не могу использовать его, потому что мой менеджер не является родительским контейнером для моего CharacterInstaller.Container

Я открыт для предложений, возможно, для рефакторинга моей установки, если это необходимо. Заранее спасибо

1 Ответ

1 голос
/ 20 января 2020

Ну, я нашел решение, но оно не очень здорово.

В установщике, привязанном к контексту сцены, свяжите List<CharacterController>

public class GameInstaller : MonoInstaller<GameInstaller>
{
    public override void InstallBindings()
    {
        Container.Bind<List<CharacterController>>().AsSingle();
    }
}

И в CharacterInstaller, добавить инстанцированный символ в внедренный список

public class CharacterInstaller : MonoInstaller<CharacterInstaller>
{
    private List<CharacterController> characters;

    [Inject]
    public void InjectDependencies( List<CharacterController> characters )
    {
        this.characters = characters;
    }

    public override void InstallBindings()
    {
        Container.BindInterfacesAndSelfTo<CharacterInstaller>()
            .AsSingle()
            .OnInstantiated<CharacterController>( ( context, character ) => characters.Add( character ) )
            .NonLazy();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...