DependencyInjection中的Singleton

时间:2015-08-25 06:31:13

标签: .net design-patterns dependency-injection

我在依赖注入中苦苦寻找单身人士的概念。我不确定是否应该实现类以支持单个/每个实例实例化以用于作为单例的类,或者它们是否应该依赖于程序员对实例化的适当设置。

如果它将在Dependency容器

中标记为singleton,则class将按预期工作
...
builder.RegisterType<ApplicationSettings>().AsSelf().SingleInstance();
...


/// <summary>
/// This allows to create many ApplicationSettings instances which each of them will have its collection of settings. 
/// Thus we cannot guarantee that one of class has complete settings
/// </summary>
public class ApplicationSettings
{
    private readonly object _locker = new object();
    private readonly Dictionary<string, object> _settings;
    private readonly ILog _log;

    public ApplicationSettings(ILog log)
    {
        _log = log;
        _settings = LoadSettings();
        Thread.Sleep(3000); //inner hardwork, e.g. cashing of something
    }

    public object GetSettings(string key)
    {
        lock (_locker)
        {
            return _settings.ContainsKey(key) ? _settings[key] : null;
        }
    }

    public void SetSettings(string key, object value)
    {
        lock (_locker)
        {
            _settings.Remove(key);
            _settings.Add(key, value);
        }
    }

    public void Remove(string key)
    {
        lock (_locker)
        {
            _settings.Remove(key);
        }
    }

    public void Save()
    {
        Thread.Sleep(5000); //Saving somewhere
    }

    private Dictionary<string, object> LoadSettings()
    {
        Thread.Sleep(5000); //Long loading from somewhere
        return new Dictionary<string, object>();
    }
}

所有需要使用ApplicationSettings类的类都将共享一个实例,因此Settings会在保存到某个地方时包含所有信息。另一方面,如果程序员没有将类标记为 SingleInstance ,则在保存时会出现问题,因为如果将其实现为替换存储位置中的整个集合,则不会保存所有设置。因此,正确的功能很大程度上取决于程序员对类的了解并将其用作单例。

在第二个例子中,我使用静态字段进行设置,这允许我使用类作为单例或每个实例的实例化而不影响核心功能(我的意思是如果将使用更多的ApplicationSettings2实例,则不会保存所有设置)< / p>

/// <summary>
/// This allows to create many ApplicationSettings2 instances which each of them will share same collection of settings. 
/// </summary>
public class ApplicationSettings2
{
    private static readonly object Locker = new object();
    private static readonly Dictionary<string, object> Settings;
    private readonly ILog _log;

    static ApplicationSettings2()
    {
        Settings = LoadSettings();
        Thread.Sleep(3000); //inner hardwork, e.g. cashing of something
    }


    public ApplicationSettings2(ILog log)
    {
        _log = log;
    }

    public object GetSettings(string key)
    {
        lock (Locker)
        {
            return Settings.ContainsKey(key) ? Settings[key] : null;
        }
    }

    public void SetSettings(string key, object value)
    {
        lock (Locker)
        {
            Settings.Remove(key);
            Settings.Add(key, value);
        }
    }

    public void Remove(string key)
    {
        lock (Locker)
        {
            Settings.Remove(key);
        }
    }

    public void Save()
    {
        Thread.Sleep(5000); //Saving somewhere
    }

    private static Dictionary<string, object> LoadSettings()
    {
        Thread.Sleep(5000);
        return new Dictionary<string, object>();
    }
}

两种类使用方法

...
builder.RegisterType<ApplicationSettings>().AsSelf().SingleInstance();
...

...
builder.RegisterType<ApplicationSettings>().AsSelf();
...

将导致相同的预期功能。唯一不同的是,单例实例化模式不会导致功能较慢(在ctor中有睡眠),但在一天结束时,更改实例化模式不会破坏任何内容。

我的问题:

  • 谁负责在依赖容器配置中定义哪个类应该用作单例?
  • 关于存储实例的信息应该在哪里?
  • 我是否应该实现打算用作单例的类,以便即使在每个实例实例化的环境中也能工作?
  • 如果我将第三方DLL的类添加到我的依赖容器配置中,谁负责通知我应该如何实现此类? (程序员如何知道他应该使用哪种实例?应该将此信息作为文档的强制性部分,还是程序员只需使用&#34;尝试/使用&#34;方法?)
  • 应该是&#34; singleton&#34;仅用作如何使系统更快的方式,但即使它们被多次实例化,也应该是单身人才能够工作? (在依赖容器配置中缺少SingleInstance关键字)

0 个答案:

没有答案