Изменение Classi c Singleton для использования с. NET Core 3.1 и DependencyInjection (DI) - PullRequest
0 голосов
/ 10 января 2020

У меня есть следующий класс, в котором я хотел бы использовать. NET Ядро с DI

public class DefaultSettingsProvider : ISettingsProvider
{
    private static DefaultSettingsProvider _instance = null;
    private string _fileName = "blundergat.settings";

    private DefaultSettingsProvider() { }

    public static DefaultSettingsProvider Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new DefaultSettingsProvider();
                if (File.Exists(_instance.GetSerializedFilePath()))
                {
                    DefaultSettingsProvider o = _instance.Deserialize();
                    _instance = o ?? _instance;
                }
                _instance.RestoreDefaults();
            }
            return _instance;
        }
    }

    public void Save()
    {
        (this as ICustomXmlSerializableObject).Serialize();
    }

    public string GetSerializedFilePath()
    {
        return Path.Combine(Environment.CurrentDirectory, _fileName);
    }

    public void RestoreDefaults(bool force = false)
    {
        if (DataSourceSettings == null || force)
            DataSourceSettings = new DataSourceSettings();

        if (IcpSolverSettings == null || force)
            IcpSolverSettings = new IcpSolverSettings();
    }

    [XmlElement, Browsable(false)]
    public DataSourceSettings DataSourceSettings { get; set; }

    [XmlElement, Browsable(false)]
    public IcpSolverSettings IcpSolverSettings { get; set; }
}

С

public interface ISettingsProvider : ICustomXmlSerializableObject
{
    void Save();

    void RestoreDefaults(bool force = false);
}

Где я настраиваю DI через

var serviceProvider = new ServiceCollection()
    .AddSingleton<IHostedService, CoreHostingService>()
    .AddSingleton<ISolverManagementService, SolverManagementService>()
    .AddSingleton<IDepthMapToPointCloudAdapter, DepthMapToPointCloudAdapter>()
    .AddSingleton<IIcpBatchSolverService, IcpBatchSolverService>()
    .AddSingleton<ISettingsProvider, DefaultSettingsProvider>()
    .AddLogging(builder =>
    {
        builder.SetMinimumLevel(LogLevel.Trace); 
        builder.AddSerilog(Log.Logger);
    })
    .BuildServiceProvider();

Это явно не будет работать, как мне нужно, поэтому я попытался изменить класс на этот

public class DefaultSettingsProvider : ISettingsProvider
{
    private static DefaultSettingsProvider instance = null;
    private string _fileName = "blundergat.settings";

    public DefaultSettingsProvider()
    {
        if (instance == null)
        {
            instance = this;
            if (File.Exists(instance.GetSerializedFilePath()))
            {
                DefaultSettingsProvider o = instance.Deserialize();
                instance = o ?? instance;
            }
            instance.RestoreDefaults();
        }
    }

    public void Save()
    {
        (this as ICustomXmlSerializableObject).Serialize();
    }

    public string GetSerializedFilePath()
    {
        return Path.Combine(Environment.CurrentDirectory, _fileName);
    }

    public void RestoreDefaults(bool force = false)
    {
        if (DataSourceSettings == null || force)
            DataSourceSettings = new DataSourceSettings();

        if (IcpSolverSettings == null || force)
            IcpSolverSettings = new IcpSolverSettings();
    }

    [XmlElement, Browsable(false)]
    public DataSourceSettings DataSourceSettings { get; set; }

    [XmlElement, Browsable(false)]
    public IcpSolverSettings IcpSolverSettings { get; set; }
}

Это хорошо работает с DI, однако, это не правильно инициализирует настройки из-за мое использование stati c `instance ', поэтому, когда я пытаюсь сделать

public A(ISettingsProvider sp)
{
    string someSetting = sp.DataSouceSettings.DataPath;
}   

DataSouceSettings, имеет значение null, поскольку оно не инициализировано. Как я могу выровнять instance.DataSouceSettings с * 1018? *? По сути, как я могу изменить этот класс для работы с DI, но также работать так же, как он работал с одноэлементным шаблоном classi c?

Ps. Для полноты.

[Serializable]
public class DataSourceSettings
{
    public DataSourceSettings()
    {
        BaseDirectory = String.Empty;
    }

    [XmlElement, Browsable(false)]
    public string BaseDirectory { get; set; }
}

1 Ответ

1 голос
/ 10 января 2020

Поскольку у вас уже есть экземпляр синглтона, просто добавьте его, а не позволяйте DI управлять временем жизни нового экземпляра - AddService :

  .AddSingleton<ISettingsProvider>(DefaultSettingsProvider.Instance)
...