Lazy Singleton,具有在构造函数中引用parent的属性

时间:2014-06-11 00:06:01

标签: c# design-patterns singleton

我有一个Singleton,它充当Web应用程序的上下文对象。这个Singleton跟随Jon Skeets非常出色Lazy Singleton model

最终结果是一个Context.Current对象,它作为许多函数的参考点。

我遇到的问题是这个对象的属性是一个名为Providers的类。它为我提供了有关一系列云提供商的OAuth信息,如ClientId。

对于大多数提供商,ClientIds会根据您的端点进行更改,因此在每个提供商的构造函数中,我检查...您猜对了,Context.Current.DeploymentType这是一个ENUM,告诉我哪个环境我&# 39; m in。

在它实例化期间调用一个对象是非常糟糕的形式,我最终得到了一个:

ValueFactory attempted to access the Value property of this instance.

现在,我可能根本不在Context.Current.DeploymentType的构造函数中引用Provider,而只是执行ENUM一遍又一遍地实例化所做的相同工作,但感觉低效的。

我可以单独创建ENUM,然后再为Context.Current创建,但这也感觉不对。

我目前的代码是:

public Providers AllProviders = Providers.Instance;

有没有办法说:

public Providers AllProviders {get; don't instantiate me until someone calls me}

1 个答案:

答案 0 :(得分:1)

这在Singleton模式中实际上并不罕见。正在初始化的对象需要从单例中访问属性,该属性尚未初始化。通常,解决这个问题的方法是延迟初始化其他实例和属性以避免此问题。

在您的示例中,由于其声明,属性在对象构造期间初始化。为了避免在对象构造期间初始化它,您可以这样做:

public Providers AllProviders
{
    get
    {
        if (this.allProviders == null) this.allProviders = Providers.Instance; // alternatively, do what Providers.Instance is actually doing
        return this.allProviders;
    }
}

如果我理解正确的话,看起来应该解决这个问题。通过进行此更改,在构造期间,属性未初始化,并且不调用Providers.Instance。只有在访问AllProviders时才会调用(然后缓存)。

当然,它不是线程安全的(除非Providers.Instance已经是线程安全的)并且您可能需要做一些工作才能使其成为线程安全的,这将通过您拥有的方法实现建议(即“在有人给我打电话之前不要实例化我”)。