Inversion of Control principle questions

Hi folks,
I’m very new to architectureing and designing applications (in particular games). I’ve had a big headache developing games before (as I now understand is because of a bad design). So now I roughly decided to dig into SOLID principle and it’s ‘D’ letter which stands for dependency inversion.
Unfortunately, I have already developed a small part of my new game without following DI principle and have to refactor code in order to move further. I’ve read a couple of articles but still have a questions.

I would realy appreciate any help here to understand this principle and apply it on real life.

I have a ‘WelcomeScene’ and three buttons on it: ‘Tryout’, ‘Signup’ and ‘Login’.

Tryout simply goes to ‘main scene’.
Signup shows ‘RegisterUser’ window.
Login shows ‘Login’ window. User can reset password in ‘ResetPassword’ window.

WelcomeMenu.cs

using UnityEngine;
using UnityEngine.UI;

namespace MyWorldTraveler.UI.Menus
{
    public sealed class WelcomeMenu : MonoBehaviour
    {
        public GameObject TestPopup;
        public GameObject LoginButton;
        public GameObject SignupButton;
        public GameObject TryoutButton;
        public GameObject CreateUserWindow;
        public GameObject LoginWindow;

        private Text loginButtonText;

        void Awake()
        {
            loginButtonText = LoginButton.GetComponentInChildren<Text>();
        }

        // Use this for initialization
        void Start()
        {
            checkFacebookInitialize();
        }

        void OnDestroy()
        {
            //prevent memory leak here.
            FB.OnInitComplete -= menuButtonsInitialize;
        }

        public void OnTryoutButtonPressed()
        {

        }

        public void OnSignupButtonPressed()
        {
            //TODO: Check internet availability here
            CreateUserWindow.SetActive(true);
        }

        public void OnLoginButtonPressed()
        {
            LoginWindow.SetActive(true);

           
        }

        private void OnSuccessfulLogin()
        {
            TestPopup.SetActive(true);
            var content = TestPopup.transform.Find("Content").GetComponent<Text>();
            content.text = "Successfuly logged in!";
            loginButtonText.text = "Logout";
        }

        public void OnOkButtonPressed()
        {
            TestPopup.SetActive(false);
        }

        private void checkFacebookInitialize()
        {
            if (FB.IsInitialized)
            {
                menuButtonsInitialize();
            }
            else
            {
                FB.OnInitComplete = menuButtonsInitialize;
            }
        }

        private void menuButtonsInitialize()
        {
            loginButtonText.text = "Logout";
            TryoutButton.GetComponent<Button>().enabled = false;
            SignupButton.GetComponent<Button>().enabled = false;
        }
    }
}

Login.cs

using System;
using UnityEngine;
using UnityEngine.UI;
using MyWorldTraveler.Social;
using MyWorldTraveler.Tools;
using com.shephertz.app42.paas.sdk.csharp.user;
using com.shephertz.app42.paas.sdk.csharp;

namespace MyWorldTraveler.UI.Social
{
    /// <summary>
    /// Login window's script at welcome scene.
    /// </summary>
    public sealed class Login : MonoBehaviour
    {
        public InputField LoginField;
        public InputField PasswordField;
        public GameObject ResetPasswordPopup;
        public Button LoginButton;

        private string _login = string.Empty;
        private string _password = string.Empty;

        void OnEnable()
        {
            ResetPasswordPopup.SetActive(false);
            LoginButton.gameObject.SetActive(false);
            UsersManager.Instance.OnPasswordResetted += OnPasswordResettedHandler;   
        }

        void OnDisable()
        {
            LoginField.text.text = string.Empty;
            PasswordField.text.text = string.Empty;
            UsersManager.Instance.OnPasswordResetted -= OnPasswordResettedHandler;   
        }

        void OnPasswordResettedHandler()
        {
            //TODO: Somehow tell a user that password has been successfuly resetted.

        }

        public void OnLoginFieldValueChanged(InputField input)
        {
            _login = input.value;
            if (_login.Length.IsPositive() && _password.Length.IsPositive())
            {
                LoginButton.gameObject.SetActive(true);
            }
            else
            {

            }
        }

        public void OnPasswordFieldValueChanged(InputField input)
        {
            _password = input.value;
            if (_password.Length.IsPositive())
            {
                LoginButton.gameObject.SetActive(true);
            }
            else
            {

            }
        }

        public void OnFacebookLoginButtonPressed()
        {
            BasicFacebookSocial.Instance.Authenticate(authenticationSuccessResponse =>
            {
                if (authenticationSuccessResponse) GoTo.MainScene();
            });
        }

        public void OnLoginButtonPressed()
        {
            if (_login.IsEmail())
            {
                UsersManager.Instance.app42loginUserByEmail(_login, _password, successAction(), failAction());
            }
            else
            {
                UsersManager.Instance.app42loginUser(_login, _password, successAction(), failAction());
            }
        }

        public void OnForgotPasswordButtonPressed()
        {
            ResetPasswordPopup.SetActive(true);
        }

        public void OnCancelButtonPressed()
        {
            gameObject.SetActive(false);
        }

        private Action<User> successAction()
        {
            return (user) =>
                {
                    GoTo.MainScene();
                };
        }

        private Action<App42Exception> failAction()
        {
            return (exception) =>
                {
                    var code = exception.GetAppErrorCode();
                    workoutLoginFail(code);
                };
        }

        private void workoutLoginFail(int errorCode)
        {

        }
    }
}

RegisterUser.cs

using UnityEngine;
using UnityEngine.UI;
using MyWorldTraveler.Social;
using MyWorldTraveler.Settings;
using MyWorldTraveler.Tools;
using System.Collections;

namespace MyWorldTraveler.UI.Social
{
    /// <summary>
    /// Register a user window's script at welcome scene.
    /// </summary>
    public sealed class RegisterUser : MonoBehaviour
    {
        public Button SubmitButton;
        public Toggle AvailabilityToggle;
        public InputField Username;
        public InputField Email;
        public Text Status;

        private string _username;
        private string _email;
        private string _password;
        private string _repassword;

        private bool _isUsernameValid;
        private bool _isEmailValid;
        private bool _isPasswordValid;

        void Start()
        {
            SubmitButton.gameObject.SetActive(false);
            AvailabilityToggle.isOn = false;
        }

        public void OnSubmitButtonPressed()
        {
            UsersManager.Instance.app42CreateUser(_username, _password, _email, successCallback: user =>
            {
                //somehow use app42's user object here
                StartCoroutine(workoutSignUpSuccess());
            }, errorCallback: fail =>
            {
                //tell a user that registration failed
                var code = fail.GetAppErrorCode();
                workoutErrorCode(code);
            });
        }

        public void OnCancelButtonPressed()
        {
            gameObject.SetActive(false);
        }

        public void OnUsernameValueChanged(InputField input)
        {
            if (input.value.Length >= GameConstants.MinimumUsernameLength)
            {
                _username = input.value;
                _isUsernameValid = true;
                AvailabilityToggle.isOn = true;
                SubmitButton.gameObject.SetActive(isSubmitAvailable());
            }
            else
            {
                //Status.text = "Username must be at least 4 characters long";
                AvailabilityToggle.isOn = false;
                _isUsernameValid = false;
                SubmitButton.gameObject.SetActive(false);
            }
        }

        public void OnEmailValueChanged(InputField input)
        {
            if (input.value.IsEmail())
            {
                _email = input.value;
                _isEmailValid = true;
                SubmitButton.gameObject.SetActive(isSubmitAvailable());
            }
            else
            {
                _isEmailValid = false;
                SubmitButton.gameObject.SetActive(false);
            }
        }

        public void OnPasswordValueChanged(InputField input)
        {
            _password = input.value;
            if (input.value.Length >= GameConstants.MinimumPasswordLength && input.text.Equals(_repassword))
            {
                _isPasswordValid = true;
                SubmitButton.gameObject.SetActive(isSubmitAvailable());
            }
            else
            {
                _isPasswordValid = false;
                SubmitButton.gameObject.SetActive(false);
            }
        }

        public void OnRepasswordValueChanged(InputField input)
        {
            _repassword = input.value;
            if (input.value.Equals(_password))
            {
                _isPasswordValid = true;
                SubmitButton.gameObject.SetActive(isSubmitAvailable());
            }
            else
            {
                _isPasswordValid = false;
                SubmitButton.gameObject.SetActive(false);
            }
        }

        private bool isSubmitAvailable()
        {
            return _isUsernameValid && _isEmailValid && _isPasswordValid;
        }

        private void workoutErrorCode(int code)
        {
            if (code.Equals(GameConstants.App42UserNameExistsErrorCode))
            {
                Username.text.text = string.Empty;
                _isUsernameValid = false;
                SubmitButton.gameObject.SetActive(false);
                AvailabilityToggle.isOn = false;
                Status.text = "This username has been already exists!";
            }
            else if (code.Equals(GameConstants.App42UserEmailExistsErrorCode))
            {
                Email.text.text = string.Empty;
                _isEmailValid = false;
                SubmitButton.gameObject.SetActive(false);
                Status.text = "User with this e-mail has been already registered!";
            }
        }

        IEnumerator workoutSignUpSuccess()
        {
            Status.color = Color.green;
            Status.text = "OK!";
            //TODO: Show visual effects
            yield return new WaitForSeconds(1f);
            GoTo.MainScene();
        }
    }
}

ResetPasswordPopup.cs

using System.Linq;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using MyWorldTraveler.Tools;
using MyWorldTraveler.Social;

namespace MyWorldTraveler.UI.Social
{
    public sealed class ResetPasswordPopup : MonoBehaviour
    {
        public Button ResetButton;
        public Text UserInputText;

        private IEnumerable _parentSelectables;
        private string _userInput;

        void Awake()
        {
            _parentSelectables = transform.parent.GetComponentsInChildren<Selectable>()
                .Where(sl => sl.transform.parent.name != transform.name)
                .AsEnumerable<Selectable>();
        }

        void OnEnable()
        {
            disableParentMonoBehaviours();
        }

        void OnDisable()
        {
            enableParentMonoBehaviours();
        }

        public void OnUserInputInfoValueChange(InputField input)
        {
            var isActive = input.value.Length.IsPositive() ? true : false;
            _userInput = input.value;
            ResetButton.gameObject.SetActive(isActive);
        }

        public void OnResetPasswordButtonPressed()
        {
            UsersManager.Instance.app42resetPassword(_userInput,
                successCallback: response =>
                {

                }, errorCallback: fail =>
                {
                    var code = fail.GetAppErrorCode();
                    workoutResetPassowrdFail(code);
                });
        }

        public void OnCancelButtonPressed()
        {
            gameObject.SetActive(false);
        }

        private void workoutResetPassowrdFail(int code)
        {
            UserInputText.text = "";

        }

        private void disableParentMonoBehaviours()
        {
            foreach (Selectable _mb in _parentSelectables)
            {
                _mb.enabled = false;
            }
        }

        private void enableParentMonoBehaviours()
        {
            foreach (Selectable _mb in _parentSelectables)
            {
                _mb.enabled = true;
            }
        }
    }
}
  1. Should I treat fields of types GameObject, Button, Text, Toggle, InputField as dependencies? Should I wrap them in an abstraction, lets say, IControl?
  2. In WelcomeMenu.cs I have calls to FB class of Facebook SDK but I have BasicFacebookSocial singleton class which performs init, authorize and logout and I have UsersManager singleton class which uses App42 services which provide login, logout and many other stuff. How can I merge these functionality into abstraction? Would it better to user interfaces or abstract classes?
  3. How to deal with dependencies from the same layer ?

I really appreciate any of your help folks.

These are coding questions, not game design questions. Good stuff, but please post it in the Scripting forum.