我已经知道要使用单例延迟加载,这是要使用的模式:
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; }
}
这不会是延迟加载。但这真的是我应该在网络应用程序中烦恼的事情吗?
答案 0 :(得分:4)
延迟加载通常意味着你懒得从数据库加载一些东西。你正在做的通常被称为“lazy initialization”(技术上“懒惰初始化”是一种实现延迟加载模式的方法)。
关于你原来的问题:首先,你不需要单身人士。如果仍需要它,here's应该如何正确地完成此操作。第三,你不需要单身人士。
答案 1 :(得分:3)
除非你有不需要单例的静态方法,否则只需要包含一个静态构造函数就可以使类变得懒惰。如果没有静态构造函数,它仍然主要是懒惰。
有关详细信息和选项,请参阅我的singleton implementation page。
我通常会在问题的底部给出你的代码 - 它很懒,除非你真的不想初始化单例,除非它会被使用。 (基本上使用beforefieldinit
set,JIT通常会确保方法中使用的每个类型都已初始化;没有beforefieldinit
它必须等到执行期间第一次实际使用该类。请参阅我的{ {3}}了解更多信息 - 但重要的是,一旦加载程序集或类似的东西,它仍然不会初始化所有单例。)
答案 2 :(得分:1)
这一切都很好,但延迟加载的重点是避免加载(通常是非托管的)资源(命中数据库,文件系统等),直到你需要为止,这样可以避免在你需要时先加载它们真的需要。单独使用单例模式本身并不一定意味着延迟加载,因为您可以在任何时候正确地创建托管实例。
如果只在进行适当的方法调用时访问您加载的任何资源,则延迟加载方面会起作用;如果,当创建单例实例时,它会执行一大堆数据库查询并保存结果,那么就我而言,它并不是延迟加载。
对于ORM场景,延迟加载通常直接指向关系中的另一个对象的加载,直到第一次访问为止,这避免了执行第二次可能不必要的查询。
然后,如果您知道在使用对象的过程中将要导航该关系(例如,如果您检索了User
以便列出他们的Posts
或者某事),那么你可能想要指示你的ORM同时加载相关的对象,这通常会提示它用连接执行单个查询,而不是循环并稍后执行多个查询;在这种情况下,你真的不想要延迟加载。
答案 3 :(得分:0)
请确保不要混淆页面加载,会话和应用程序生命周期。那就是说,你确定要使用静态单例实例吗?一旦创建,它将一直存在,直到应用程序(网络服务器)关闭或您运行 iisreset 。
如果您希望每页加载一个延迟加载的实例,或者如果您想要每个用户一个HttpContext.Current.Items
,请考虑在HttpContext.Current.Session
中缓存它。