views:

210

answers:

4

I've learned that to have a singleton lazy loading, this is the pattern to use:

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; }
    }
}

But a more simple pattern would be:

private static readonly MyObject _instance = new MyObject();

private MyObject()
{
}

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

This wouldn't be lazy loading. But is this really something that I should bother about in a web application?

+3  A: 

Unless you have static methods which don't need the singleton, just including a static constructor is enough to make the class lazy. Without the static constructor it's still mostly lazy.

See my singleton implementation page for more details and options.

I'd normally the code you gave at the bottom of the question - it's lazy enough, unless you really don't want to initialize the singleton unless it's going to be used. (Basically with beforefieldinit set, the JIT will generally make sure that every type used in a method is initialized; without beforefieldinit it has to wait until the first actual use of the class during execution. See my beforefieldinit page for more information - but the important point is that it's still not going to initialize all singletons as soon as the assembly is loaded, or anything like that.)

Jon Skeet
+4  A: 

Lazy loading usually implies that you're lazily loading something from a database. What you're doing is usually called "lazy initialization" (technically "lazy initialization" is a method of implementation of a lazy loading pattern).

As to your original questions: first off, you don't need a singleton. If you still need it, here's how this should be done properly. Third, you don't need a singleton.

Anton Gogolev
+1  A: 

That's all well and good, but the point of lazy loading is to avoid loading (usually unmanaged) resources (hitting a database, the filesystem, etc.) until you need to, which avoids loading them pre-emptively when you don't really need to. Use of the singleton pattern, in of itself, doesn't necessarily imply lazy-loading, since you can quite correctly create the managed instance at any point.

The lazy-loading aspect comes into play if any resources you load are only accessed when the appropriate method call is made; if, when that singleton instance is created, it does a whole bunch of database queries and stashes the result, then it's not lazy loading as far as I'm concerned.

With respect to ORM scenarios, lazy-loading usually refers directly to deferring the load of another object in a relationship until the first access, which avoids performing a second, potentially unnecessary query.

Then again, if you know you're going to be navigating that relationship in the course of your use of the object (i.e. if you've retrieved a User in order to list their Posts or something), then you probably want to instruct your ORM to load the related objects at the same time, which will usually tip it off to perform a single query with a join, rather than looping through and performing multiple queries later; in this case, you don't really want lazy-loading.

Rob
A: 

Be sure not to confuse page load, session and application lifetime. That said, are you sure you want to use a static singleton instance? Once created, it will live until the application (the webserver) is shutdown or you run iisreset.

Consider caching it in HttpContext.Current.Items instead if you want one lazily loaded instance per page load, or perhaps in HttpContext.Current.Session if you want one per user.

weazl