Реализуйте idisposable на изменчивых объектах c#

Я использую шаблон проектирования singleton для классов Business Layer и Data Access Layer на C#.

Мой класс выглядит следующим образом:

using System;
using System.Data;
using System.Data.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;

public class CabBookingDao: IDisposable
{
    private static volatile CabBookingDao _instance;
    private static readonly object SyncRoot = new Object();

    private readonly DatabaseProviderFactory _factory;
    private readonly Database _db;
}

public static CabBookingDao Instance
{
    get
    {
        if (_instance == null)
        {
            lock (SyncRoot)
            {
               if (_instance == null)
                 _instance = new CabBookingDao();
            }
        }
        return _instance;
    }
}

private CabBookingDao()
{
    _factory = new DatabaseProviderFactory();
    _db = _factory.Create("MyDbContext");
}

public void Dispose()
{
   GC.SuppressFinalize(this);
}

Здесь я пытаюсь реализовать IDisposable для этого класса и получаю предупреждение от анализатора кода VS, например:

CA1063 Implement IDisposable correctly Provide an overridable implementation of Dispose(bool) on 'CabBookingDao' or mark the type as sealed. A call to Dispose(false) should only clean up native resources. A call to Dispose(true) should clean up both managed and native resources CabBookingDao.cs

По этому предупреждению я понял, что предполагаю создать метод, как показано ниже:

protected virtual void Dispose(bool disposing)
{
    if (disposing) 
    {
        // free managed resources
    }
    // free native resources if there are any.
}

Но я не понимаю, какие объекты мне нужно здесь избавиться? Если я удалю _экземпляр, повлияет ли это на поведение Singleton?

But, I'm confused about what objects do I need to dispose here? Нестатические члены объекта, которые не используются совместно с другими объектами.
mjwills 10.08.2018 14:40

Вы имеете в виду, в моем случае, _factory и _db?

55SK55 10.08.2018 14:46
Вероятно, да. Это зависит от ряда факторов. Например, у вас может быть контейнер IoC, что май означает, что вам вообще не нужен Dispose (поскольку контейнер будет обрабатывать его за вас). Но мой первый комментарий - это разумное «общее правило».
mjwills 10.08.2018 14:48

Чтобы было ясно, я бы не стал использовать вашу технику lock - я бы просто использовал вместо нее Lazy (ну, технически я бы использовал stackoverflow.com/a/42567351/34092).

mjwills 10.08.2018 14:51

@ 55SK55 Я предлагаю отказаться от шаблона ленивой инициализации с двойной проверкой, так как работать с изменчивыми полями практически невозможно. Для этого есть несколько проверенных фреймворков: Ленивый <T> или LazyInitializer.

Adam Simon 10.08.2018 14:52

Я бы предложил что-то вроде private static Lazy<CabBookingDao> _instance = new Lazy<CabBookingDao>(() => new CabBookingDao());. Опять же, для большей безопасности я бы использовал LazyWithNoExceptionCaching - stackoverflow.com/questions/34529533/….

mjwills 10.08.2018 15:05

Если вы выключите его и воссоздадите нет как синглтон, это просто объект. Вы не реализуете одноразовый синглтон. Синглтоны автоматически выходят из области видимости при выключении AppDomain (что случается, когда программа завершается), и обычно у вас есть только один, если вы не создаете дочерние AppDomain.

MickyD 10.08.2018 15:05
0
7
109
0

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