如何使用zenject在Mono3d中将MonoBehaviour类注入非Monobehaviour?

问题描述 投票:0回答:1

我想尽可能地组织我的代码,但是我在组织代码方面遇到了一些麻烦。我尝试使用SOLID原理并创建单独的实体。我想使用MVVM查看(unity-weld as well)和DI容器(zenject as well)。

这是我的第一个项目,我正在尝试组织代码。

我的问题是如何使用LoginViewModel类中的zenject容器将LoginController作为静态类注入到GameInstaller中。

[Binding]
public class LoginViewModel : MonoBehaviour, INotifyPropertyChanged
{

    private string _username = "";
    private string _passsword = "";
    private string _errorMessage = "";
    private bool _autologin = false;

    [Inject]
    private LoginController _loginController;

    [Binding]
    public string Username {
        get
        {
            return _username;
        }
        set
        {
            if (_username == value)
            {
                return; // No change.
            }

            _username = value;
            Debug.Log($"SET username: {value}");
            OnPropertyChanged("Username");
        }
    }

    [Binding]
    public string Password {
        get
        {
            return _passsword;
        }
        set
        {
            if (_passsword == value)
            {
                return; // No change.
            }

            _passsword = value;
            Debug.Log($"SET password: {value}");
            OnPropertyChanged("Password");
        }
    }

    [Binding]
    public bool Autologin {
        get
        {
            return _autologin;
        }
        set
        {
            if (_autologin == value)
            {
                return; // No change.
            }

            _autologin = value;
            Debug.Log($"SET autologin: {value}");
            OnPropertyChanged("Autologin");
        }
    }

    [Binding]
    public void LoginButtonClick()
    {
        Debug.Log("LoginButtonClick");

        _loginController.Login(this);
        //ErrorMessage = "blabla";
    }

    [Binding]
    public string ErrorMessage
    {
        get
        {
            return _errorMessage;
        }
        set
        {
            if (_errorMessage == value)
            {
                return; // No change.
            }

            _errorMessage = value;
            Debug.Log($"SET errorMessage: {value}");
            OnPropertyChanged("ErrorMessage");
        }
    }

    /// <summary>
    /// Event to raise when a property's value has changed.
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

public class LoginController
{
    private readonly ApiController _apiController;

    [Inject]
    private readonly LoginViewModel _loginViewModel;

    public LoginController(ApiController apiController)
    {
        _apiController = apiController;
    }

    public void Login(LoginViewModel loginViewModel)
    {
        try
        {
            string userJson = _apiController.PostLogin(loginViewModel.Username);

            _loginViewModel.ErrorMessage = "bla bla trololo";
            Debug.Log(userJson);
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
}

public class GameInstaller : MonoInstaller
{
    [Inject]
    Settings _settings = null;

    public override void InstallBindings()
    {
        InstallViewModels();
        InstallServices();
        InstallSignals();
        InstallControllers();
    }

    private void InstallViewModels()
    {
        Container.Bind<LoginViewModel>().AsSingle();
    }

    private void InstallControllers()
    {
        Container.Bind<LoginController>().AsSingle().NonLazy();
        Container.Bind<ApiController>().AsSingle().NonLazy();
    }

    private void InstallServices()
    {
    }

    private void InstallSignals()
    {
    }

    [Serializable]
    public class Settings
    {
    }
}
c# unity3d dependency-injection zenject
1个回答
0
投票

让我们从这里开始:https://unitylist.com/p/ja3/Unity-MVVM

ViewModel(或VM)是保存将在视图上呈现的数据的东西。它包含可以绑定到视图元素的所有属性。所有ViewModel都继承自INotifyPropertyChanged,它在数据更改和需要更新UI元素时向系统发出警报。

由于ViewModel本质上是一个简单的对象而不是服务,所以我认为不需要将其注入任何地方。

您可以做的是注入Factory并从中获取ViewModel。

在您的代码中,您试图将控制器注入到ViewModel中,而不是相反。

© www.soinside.com 2019 - 2024. All rights reserved.