【问题标题】:Objects inside singletons in .Net.Net 中单例内的对象
【发布时间】:2016-12-13 14:02:00
【问题描述】:

举一个真实的例子。这是下面的类:

public class HttpClientWrapper : IHttpClientWrapper
{
    private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();
    private readonly IStatsDPublisher _statsDPublisher;
    private readonly HttpClient _client;

    public HttpClientWrapper(IStatsDPublisher statsDPublisher, string baseAddress)
    {
        _statsDPublisher = statsDPublisher;
        _client = new HttpClient();


        _client.BaseAddress = new Uri(baseAddress);
        ServicePointManager.FindServicePoint(_client.BaseAddress).ConnectionLeaseTimeout = (int)TimeSpan.FromSeconds(60).TotalMilliseconds;
    }

    public async Task PostAsync<T>(string resource, T content)
    {
        var stringContent = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8,"application/json");

        var name = typeof(T);

        using (var timer = _statsDPublisher.StartTimer($"HttpClient.{name.Name}.Post"))
        {
            try
            {
                await _client.PostAsync(resource, stringContent).ContinueWith(
                    (postTask) =>
                    {
                        postTask.Result.EnsureSuccessStatusCode();
                    });

                timer.StatName = $"{timer.StatName}.Success";
            }
            catch (Exception ex)
            {
                timer.StatName = $"{timer.StatName}.Failure";
                Logger.ExtendedException(ex, "Failed to Post.", new {Url = resource, Content = content});
                throw;
            }
        }
    }

    public async Task PutAsync<T>(string resource, T content)
    {
        var stringContent = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8,
            "application/json");

        var name = typeof(T);

        using (var timer = _statsDPublisher.StartTimer($"HttpClient.{name.Name}.Put"))
        {
            try
            {
                await _client.PutAsync(resource, stringContent).ContinueWith(
                   (postTask) =>
                   {
                       postTask.Result.EnsureSuccessStatusCode();
                   });

                timer.StatName = $"{timer.StatName}.Success";
            }
            catch (Exception ex)
            {
                timer.StatName = $"{timer.StatName}.Failure";
                Logger.ExtendedException(ex, "Failed to Put.", new { Url = resource, Content = content });
                throw;
            }
         }
    }

} }

在 IoC 中,我们执行以下操作:

 Bind<IHttpClientWrapper>()
                .To<HttpClientWrapper>()
                .InSingletonScope()

所以现在是一个单例。我应该假设每次我们调用 HttpClientWrapper 时,我们是在处理同一个 HttpClient 实例,还是每次我们创建一个新实例?我相信每次访问 HttpClientWrapper 时,尽管是单例,您都会创建一个新的 HttpClient 实例。可以请教吗?

谢谢

【问题讨论】:

    标签: .net memory memory-management singleton


    【解决方案1】:

    单例意味着您在整个应用程序中只有一个类的单个实例。您根本无法创建该类的另一个实例。并且在你的单例中使用对象总是会返回相同的实例。 但是,您仍然可以在单例之外创建其他类的新实例。 所以答案显然是“不”。

    希望对您有所帮助。

    【讨论】:

    • Singleton 表示一个实例。这很清楚。因此,您是说 OrderApiClient 中的 A 和 B 对象不是单例,但每次调用 OrderAPiCLient 时,您都有一个实例,但在此类中,您会创建 A 和 B 的新实例。对吗?
    • 让我们更简洁地谈谈。给定您的类 OrderApiClient 在创建时创建类 A 的新实例。您的代码通过一个属性访问OrderApiClient.A,该属性返回在OrderApiClient 实例化时创建的实例。因此,您将始终拥有相同的 A 实例,而 A 不会是单例。您也可以随时在OrderApiClient 或其他任何地方创建A 的新实例。
    • 感谢您的回复。
    • 感谢您的回复。但是,如果您在单例类中有一个方法: publc Get A(string address) { var a = new A();返回一个;}。您确实创建了新实例 A 并且您的单例将返回 A 的新实例。我是否错误地断定您的单例 OrderApiClient 将返回 A 的新实例?
    • 正确。当总是创建新实例时,您将获得新实例:-)
    猜你喜欢
    • 2011-01-24
    • 2023-04-06
    • 2021-12-03
    • 1970-01-01
    • 2023-04-05
    • 2010-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多