更改经典的Singleton以与.NET Core 3.1和DependencyInjection(DI)一起使用

问题描述 投票:0回答:1

我有下面的类,我想在带.NET Core的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配置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很好用,但是由于我使用静态`instance“,所以不能正确初始化设置,所以当我尝试这样做时

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

DataSouceSettings为空,因为它没有初始化。如何将instance.DataSouceSettingssp.DataSouceSettings对齐?本质上,我该如何修改此类以使其与DI一起使用,又如何以经典的Singleton模式进行操作?

Ps。为了完整性。

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

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

我想在.NET Core中使用DI公共类DefaultSettingsProvider:ISettingsProvider {private static DefaultSettingsProvider _instance = null; ...

c# singleton settings
1个回答
0
投票

由于您已经有一个单例实例,只需添加它而不是让DI管理新实例的生存期-AddService

© www.soinside.com 2019 - 2024. All rights reserved.