views:

1275

answers:

6

I have seen numerous examples of lazy loading - what's your choice?

Given a model class for example:

public class Person
{
    private IList<Child> _children;
    public IList<Child> Children
    {
        get {
            if (_children == null)
                LoadChildren();
            return _children;
        }
    }
}

The Person class should not know anything about how it's children are loaded .... or should it? Surely it should control when properties are populated, or not?

Would you have a repository that couples a Person together with its children collection or would you use a different approach, such as using a lazyload class - even then, I don't want a lazyload class blurring in my model architecture.

How would you handle performance if first requesting a Person and then its Children (i.e. not lazy loading in this instance) or somehow lazy loading.

Does all this boil down to personal choice?

A: 

I'm thinking that this is precisely the kind of problem that is best handled by AOP (e.g., PostSharp). Have your lazy loading as an aspect and then use it to decorate whatever property you want to be loaded lazily. Disclaimer: haven't tried it; just thinking that it should work.

Dmitri Nesteruk
+8  A: 

The best lazy loading is avoiding it ;) Thread safety is an immediate problem you'll have to handle. I have no count of how often I have seen production systems with 8 cpu cores run lazy loading 8 times for every single lazy loading pattern in use. At least on server startups all server cores have a tendency to end up in the same places.

Let a DI framework construct it for you instead, if you can. And if you cannot, I still prefer explicit construction. So all sorts of AOP magic simply do not cut it with me, go for explicit construction outside the class. Don't put it inside the person class, just make a service that constructs the objects in the proper manner.

Introducing "magic" layers that more or less transparently do these things seem like a nice idea, but I have yet to come across implementations that do not have unforseen and problematic consequences.

krosenvold
Thanks for your time, can you elaborate on using a DI framework and explicit construction?
Tim Peel
I think he was saying that having the Person class explicitly create the children (with LoadChildren() presumably) during its own initialization leaves no doubt as to the state of _children. And Dependency Injection, well there are many threads here that're better than me in a comment.
JMD
Also - you lose the atomicity of the query. And more often than not the most efficient overall strategy is to issue a single query with (outer?) joins for the child records and get everything in one transaction, rather than spreading it out across multiple database sub-hits.
le dorfier
@Tim I was a little out-of-order in my post; try to make a service that constructs the whole structure you require - that is explicit construction. Don't try to hide object construction, just do it in the right place. DI construction is a different ballgame and may be less optimal for domain objects
krosenvold
@Krosenvold - no offence taken ;) - I too don't like the "magic" layers. They confuse the situation in my eyes. So your approach would be similar to @Toran below?
Tim Peel
@Le Dorfier - Agree with performance concerns. There comes a tipping point though when an object may have too many child relationships to warrant loading everything at once. What do you do in these situations?
Tim Peel
I would also like to know what to do in the "too many child relationships" situation
Schneider
A: 

I talked about a solution I use to accomplish lazy loading here

Toran Billups
Thanks for your time, is this not just another dependency though? I am interested in the approach though.
Tim Peel
+1  A: 

You can use the Lazy<T> class I talked about here : http://stackoverflow.com/questions/130292/what-is-the-proper-way-to-inject-a-data-access-dependency-for-lazy-loading/522547#522547

There is also link to a more detailed blog post there...

Think Before Coding
+1  A: 

You can use the Virtual Proxy pattern, along with the Observer pattern. This would give you lazy loading without the Person class having explicit knowledge about how Children are loaded.

moffdub
A: 

I just asked a related question here, but it was heavier on the Immutability & Thread Safety tack. Lots of good answers and comments. You may find it useful.

Scott Whitlock