C# – Lazy loaded property signatures in business objects

cclass-designlazy-initialization

Let's say I am designing business objects around a poorly optimized database that have no ability to change.

I have a Person object with a ShippingAddress property. The ShippingAddress is very expensive to load and located in a separate table, and a minority of pages use it. There are times when thousands of Person objects need to be loaded on a single page so eating the performance hit is not an option. This makes lazy loading the ShippingAddress ideal for this situation.

However, from a business logic/consumer/signature perspective there is no reason ShippingAddress should be any different the eagerly loaded Name property. For this reason, I have decided to make ShippingAddress' public property signature a regular string while its private backing field is C#'s Lazy. The question is, how should I set it? I have come up with two options that maintain separation of data access logic:

Option 1, using overloaded java style set method seems like better OO and more consistent from a internal perspective since I leverage method overloading:

    Lazy<string> _address;
    public string Address { get { return _address == null ? null : _address.Value; } }
    public void SetAddress(Func<string> address)
    {
        _address = new Lazy<string>(address);
    }
    public void SetAddress(string address)
    {
        SetAddress(() => address);
    }

Option 2 seems much better/consistent from a consumer's perspective, but the two setting methods seem very disjointed in a way that bothers me:

    Lazy<string> _address;
    public string Address 
    { 
        get { return _address == null ? null : _address.Value; }
        set { SetAddress(() => value); }
    }
    public void SetAddress(Func<string> address)
    {
        _address = new Lazy<string>(address);
    }

Does anyone with more experience than I (Most of you I assume) using C#'s lazy class have any ideas as to which is better and why?

Best Answer

When it comes to a BO, the consumer should not see field is lazy loaded or not and it's better to present as any other property (without exposing methods accepting Func parameters)., I'd rather go with the second approach without having the public method SetAddress

Lazy<string> _address;

public string Address 
{ 
    get { return _address == null ? null : _address.Value; }
    set { _address = new Lazy<string>(() => value); }
}