Использование Синглетона в приложении C#



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



У меня есть кое-что это работает, но я не думаю, что это самый правильный путь, и что я могу пропустить шаг.



У меня есть простой файл класса в моей программе под названием clsRegistry, реализованный как синглтон.



public sealed class clsRegistry
{
//http://tech.pro/tutorial/625/csharp-tutorial-singleton-pattern

private static clsRegistry RegInstance;

private clsRegistry() { }

public static clsRegistry GetInstance()
{
lock (typeof(clsRegistry))
{
if (RegInstance == null)
{
RegInstance = new clsRegistry();
}
return RegInstance;
}
}

public string dataBase { get; set; }
public string userId { get; set; }
public string passWord { get; set; }

public void ReadKeys()
{
//http://stackoverflow.com/questions/1388787/information-in-registry
RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SoftwareKey1Key2Key3");
dataBase = key.GetValue("ADODataSource").ToString().Trim();
userId = key.GetValue("ServerUserID").ToString().Trim();
passWord = key.GetValue("ServerPassword").ToString().Trim();
}
} // end class definition


Который при вызове из основного метода реализует корректно и вызывает один открытый метод (ReadKeys) в классе



static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// create instance of registry class
clsRegistry regData = clsRegistry.GetInstance();

// call method
regData.ReadKeys();

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new frmMain());
Application.Run(new frmLogin());
}
}


После создания синглтона класса у меня загружается небольшая форма входа в систему, и я хочу, чтобы имя базы данных из синглтона отображалось в форме и вот тут-то у меня и нет более чем элегантного кода.



private void frmLogin_Load(object sender, EventArgs e)
{
// create a 'new' instance to the singleton?
clsRegistry regData = clsRegistry.GetInstance();

lblDataBase.Text = regData.dataBase;
}


Действительно ли мне нужно создать еще одну ссылку на мой синглетный объект, чтобы прочитать некоторые значения (или позже вызвать другой метод), или я где-то пропустил шаг? Я действую в предположении, что как только я создаю экземпляр класса как синглет, и он остается в том же пространстве имен, я могу получить доступ к любому общедоступному значению или методу. - Нет?



Для справки я использую Visual Studio 2010 и платформу 4.0 (и да Я еще один классический разработчик VB, который наконец-то прыгает с корабля)

512   3  
c#

3 ответов:

Прежде всего: в C# для этого не нужны блокировки и т. д. Просто создайте экземпляр с помощью статической инициализации,и вы будете threadsafe и хорошо идти.

public sealed class ClsRegistry
{
    private static ClsRegistry RegInstance = new ClsRegistry();

    private clsRegistry() { }

    public static ClsRegistry Instance {
        get { return RegInstance; }
    }

    public string DataBase { get; set; }
    public string UserId { get; set; }
    public string PassWord { get; set; }

    public void ReadKeys()
    {
        // ...
    }
}
После этого вы можете просто получить доступ к синглету и его свойствам / методам через ClsRegistry.Instance без необходимости сначала присваивать его новой переменной:
static void Main()
{
    ClsRegistry.Instance.ReadKeys();
    // ...
}

И

private void frmLogin_Load(object sender, EventArgs e)
{
    lblDataBase.Text = ClsRegistry.Instance.DataBase;
}

Пожалуйста, обратите внимание, что я изменил названия вашего класса и свойств так, чтобы каждая первая буква была заглавной, что является своего рода соглашение в C#

Во-первых, Microsoft имеет рекомендации для реализации синглтона конкретно в C#, что объясняет в мельчайших деталях лучший способ создания единого и многопоточного синглтонного класса.

Что касается вашего кода:

  1. Вы не создаете другой экземпляр вашего объекта при вызове GetInstance. Код возвращает ранее созданный экземпляр. Он создает новый экземпляр класса только в том случае, если он равен null (только один раз).

  2. Вы должны сделать Экземпляр свойства вместо метода в .NET (это просто чище).

  3. Вы должны придерживаться Pascal case при написании кода .NET, если вы пишете код Java, я бы посоветовал вам придерживаться camelCase, потому что это стандартный корпус для языка.

Чтобы получить доступ к значениям, необходимо запросить ссылку на синглет, да. Вам не нужно хранить эту ссылку в локальной переменной, если вы не хотите, хотя вы, конечно, можете. Если вы не хотите, вы можете получить доступ к значению непосредственно из экземпляра:

lblDataBase.Text = clsRegistry.GetInstance().dataBase;

Comments

    Ничего не найдено.