Как получить доступ к переменной из разных классов?

У меня есть класс UserControl, класс Main Form и класс DbConn.

Я хочу получить доступ к классу DbConn «как посредник» из обоих других классов. Таким образом, UserControl должен установить строку класса DbConn, а класс основной формы должен снова прочитать строку из него.

(Или он должен сделать это на данный момент. Позже этот класс DbConn должен отслеживать учетные данные соединения и обрабатывать все соединения с моей базой данных, чтобы получить некоторую ясность между отдельными частями. На данный момент все находится в классе основной формы, но с запланированными дополнениями этот код будет сложно поддерживать, если я не разделю класс на разные классы, которые должны обрабатывать только одно, например DatabaseConnection, разные Frontendparts и т. д.)

Это UserControl Класс:

namespace mySQL_Project
{
    public partial class SettingsControl : UserControl
    {
        DbConn dbConn = new DbConn();

        public SettingsControl()
        {
            InitializeComponent();
        }
        private void Button_SetDB_Click(object sender, EventArgs e)
        {
            String connectString = tb_stringtext;
            dbConn.connParamNewSQLite(connectString);
        }
    }
}

Это Main Класс:

namespace mySQL_Project
{
    public partial class Main : Form
    {
        DbConn dbConn = new DbConn();

        public Main()
        {
            InitializeComponent();
        }
        private void textBox_getDBConn_Click(object sender, EventArgs e)
        {
           label_dbinfo.Text = dbConn.connParamGetSQLite(); //should get Text set in userControl
        }
    }
}

а это DbConn Класс:


namespace mySQL_Project
{
    internal class DbConn
    {
        private string conn;
        public void connParamNewSQLite(string connectionString)
        {
            conn = connectionString;
        }

        public string connParamGetSQLite()
        {
            return conn;
        }

        public int DbGetSumApples(){
            cmd = new SQLiteCommand();
            cmd.CommandText = @"SELECT sum FROM inv WHERE ID=@AI";
            cmd.Parameters.AddWithValue("@AI", "3"); //Apple-ID
            cmd.Connection = conn;
            return cmd.ExecuteScalar().ToString();
        }
    }
}

Но это не дает мне строку, которую я установил в классе UserControl.

Идея состоит в том, чтобы иметь что-то вроде глобальной переменной. Например. Класс передал некоторые переменные подключения из одного класса с помощью функции connParamNewSQLite(), а другой класс будет использовать, например, функцию DbGetSumApples() в том же классе DbConn для установления соединения с базой данных. Тогда функции DbGetSumApples() потребуются параметры соединения, переданные ранее функцией connParamNewSQLite().
(Функция DbGetSumApples() не будет работать как есть, но я надеюсь прояснить, что в конечном итоге должен делать класс DbConn. Кроме того, экземпляр класса DbConn создается дважды, потому что в противном случае я не смог бы использовать функции во втором классе)

Что мне следует изменить в коде, чтобы оба класса знали класс DbConn? Или есть ли лучший подход к решению этой проблемы в виде «хорошей практики кодирования»? (например, принимая во внимание несколько потоков, даже если это пока не запланировано.)

Следующее может представлять интерес: stackoverflow.com/a/69743297/10024425 (это VB.NET, но эти концепции применимы и к C#).

user246821 17.04.2024 20:39

@user246821 user246821 Хм, я не знаю, не сделает ли это код еще более запутанным, если я буду обрабатывать все данные из MainForm. Я хочу разделить свою основную форму на разные подформы (UserControls). Несколько из этих подформ необходимо подключиться к базе данных, что я хочу сделать с помощью класса DbConn, поэтому только этот класс должен обрабатывать, например. учетные данные для подключения к базе данных. Могу ли я, например. передать в UserControls только класс DbConn, чтобы экземпляр класса DbConn создавался только один раз?

ElektrischInkorrekt 18.04.2024 10:30

В указанном сообщении передача данных между формами обсуждается в общем смысле. Однако в большинстве случаев SQL-соединение должно использовать оператор using. Сами данные могут передаваться, но соединения, скорее всего, не должно быть.

user246821 18.04.2024 18:38

Следующее может быть интересно: stackoverflow.com/a/74885060/10024425.

user246821 18.04.2024 18:39
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы создаете только один класс DbConn, вы можете реализовать его как синглтон.

public sealed class DbConn
{
    private static DbConninstance = null;
    private static readonly object padlock = new object();
    private string conn;

    public static DbConn Instance
    {
        get
        {
            lock (padlock)
            {
                if (instance == null)
                {
                    instance = new DbConn();
                }
                return instance;
            }
        }
    }
    public void connParamNewSQLite(string connectionString)
    {
        conn = connectionString;
    }

    public string connParamGetSQLite()
    {
        return conn;
    }

    public int DbGetSumApples(){
        cmd = new SQLiteCommand();
        cmd.CommandText = @"SELECT sum FROM inv WHERE ID=@AI";
        cmd.Parameters.AddWithValue("@AI", "3"); //Apple-ID
        cmd.Connection = conn;
        return cmd.ExecuteScalar().ToString();
    }
}

Таким образом, вам не понадобится глобальная переменная. Вместо этого вы можете вызвать его сейчас из другого класса, просто назвав его так: DbConn.Instance.DbGetSumApples()

Например:

public partial class SettingsControl : UserControl
{

    public SettingsControl()
    {
        InitializeComponent();
    }
    private void Button_SetDB_Click(object sender, EventArgs e)
    {
        String connectString = tb_stringtext;
        DbConn.Instance.connParamNewSQLite(connectString);
    }
}

Вот еще материал о шаблоне Singleton. Реализация шаблона Singleton на C#

Другие вопросы по теме