0

我了解到要进行单例延迟加载,这是要使用的模式:

private MyObject()
{
}

public static MyObject Instance
{
    get { return SingletonCreator.CreatorInstance; }
}

private static class SingletonCreator
{
    private static readonly MyObject _instance = new MyObject();

    public static MyObject CreatorInstance
    {
        get { return _instance; }
    }
}

但更简单的模式是:

private static readonly MyObject _instance = new MyObject();

private MyObject()
{
}

public static MyObject Instance
{
    get { return _instance; }
}

这不会是延迟加载。但这真的是我应该在 Web 应用程序中烦恼的事情吗?

4

4 回答 4

4

延迟加载通常意味着您正在从数据库中延迟加载某些内容。您所做的通常称为“延迟初始化”(技术上“延迟初始化”是延迟加载模式的一种实现方法)。

至于您最初的问题:首先,您不需要单身人士。如果您仍然需要它,请按照以下说明正确完成此操作。第三,你不需要单例。

于 2009-05-06T10:50:07.917 回答
3

除非您有不需要单例的静态方法,否则仅包含静态构造函数就足以使类变得懒惰。如果没有静态构造函数,它仍然主要是惰性的。

有关更多详细信息和选项,请参阅我的单例实现页面

我通常会使用您在问题底部提供的代码 - 它足够懒惰,除非您真的不想初始化单例,除非它将被使用。(基本上使用beforefieldinitset,JIT 通常会确保方法中使用的每个类型都被初始化;没有beforefieldinit它必须等到执行期间第一次实际使用该类。有关更多信息,请参阅我的beforefieldinit页面- 但重要的一点是一旦加载程序集或类似的东西,它仍然不会初始化所有单例。)

于 2009-05-06T10:48:06.253 回答
1

这一切都很好,但是延迟加载的目的是避免加载(通常是非托管的)资源(访问数据库、文件系统等),直到您需要,这样可以避免在您不真正加载时抢先加载它们需要。使用单例模式本身并不一定意味着延迟加载,因为您可以在任何时候完全正确地创建托管实例。

如果您加载的任何资源仅在进行适当的方法调用时才被访问,那么延迟加载方面就会发挥作用;如果在创建该单例实例时,它会执行一大堆数据库查询并存储结果,那么就我而言,它不是延迟加载。

对于 ORM 场景,延迟加载通常直接指将关系中的另一个对象的加载延迟到第一次访问,这样可以避免执行第二次可能不必要的查询。

再说一次,如果你知道你将在使用对象的过程中导航该关系(即,如果你检索 aUser以列出它们Posts或其他东西),那么你可能想要指示你的 ORM同时加载相关对象,这通常会提示它使用连接执行单个查询,而不是循环并稍后执行多个查询;在这种情况下,您并不真正想要延迟加载。

于 2009-05-06T10:50:31.927 回答
0

确保不要混淆页面加载、会话和应用程序生命周期。也就是说,您确定要使用静态单例实例吗?一旦创建,它将一直存在,直到应用程序(网络服务器)关闭或您运行iisreset

HttpContext.Current.Items如果您希望每个页面加载一个延迟加载的实例,或者HttpContext.Current.Session如果您希望每个用户一个,则考虑缓存它。

于 2009-05-06T11:12:17.473 回答