【问题标题】:How to inject MonoBehaviour class to non Monobehaviour in Unity3d with zenject?如何使用 zenject 在 Unity3d 中将 MonoBehaviour 类注入到非 Monobehaviour?
【发布时间】:2020-04-22 14:57:00
【问题描述】:

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

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

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

[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】:

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2021-10-19
      • 1970-01-01
      • 2015-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多