Использование экземпляра Singleton внутри статического метода - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть вызов со статическим методом в моем веб-приложении.Этот метод использует одноэлементный экземпляр другого класса.Этот одноэлементный экземпляр в основном является HttpClient для выполнения некоторых запросов API.

В настоящее время у меня нет какого-либо механизма для автоматизации многопользовательского тестирования по этому вопросу.Есть ли какие-либо последствия этого подхода?Я знаю, что обычный статический метод является поточно-ориентированным, если мы не используем внутри него статические переменные.Но я не уверен, как он себя ведет в случае синглтона.

public static class API
{
    private static System.Net.Http.HttpClient httpClient;

    public static System.Net.Http.HttpClient Instance
    {
        get
        {
            return httpClient ?? (httpClient = new System.Net.Http.HttpClient());
        }
    }
}

public static async Task<string> GetData(string id)
{
    HttpResponseMessage response = await 
    API.Instance.GetAsync(string.Format(requestURL, id));
    response.EnsureSuccessStatusCode();

    // return URI of the created resource.
    return await response.Content.ReadAsStringAsync();
}

1 Ответ

0 голосов
/ 20 февраля 2019

Чтобы избежать проблем с многопоточностью, вам необходимо как минимум реализовать единый потокобезопасный способ.Эта статья Джона Скита описывает некоторые способы создания одноэлементного экземпляра безопасным для потоков способом.Кроме того, вы должны убедиться, что методы синглтона могут обрабатывать параллельные запросы или использовать lock для синхронизации вызовов.

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

  • С первого взгляда разработчик не видит, что ваши методы полагаются на одноэлементный экземпляр.Это скрытая зависимость.
  • Кроме того, вы не можете легко изменить экземпляр в тех случаях, когда вам нужно другое поведение, например, в тестах.

Поэтому я хотел бы подумать о том, действительно ли нужен синглтон или вы можете добавить его в качестве параметра в методы, где он необходим:

public static async Task<string> GetData(API api, string id)
{
    HttpResponseMessage response = await 
    api.Instance.GetAsync(string.Format(requestURL, id));
    response.EnsureSuccessStatusCode();

    // return URI of the created resource.
    return await response.Content.ReadAsStringAsync();
}

Выможет изменить метод на метод расширения, который вы можете вызвать следующим образом:

var result = await API.Instance.GetData("123");

Вы просто должны добавить this к подписи:

public static async Task<string> GetData(this API api, string id)
{
  // ...
}     
...