I very, very strongly recommend against implementing lazy loading within the context of an object. Lazy loading is rarely a good idea in any case, and is usually a symptom of data-centric object design.
However, there are some cases where lazy loading of child objects can make sense, because the use case calls for incremental creation of objects/information. That may be the case here, you'll have to be the judge.
If you are going to use lazy loading, it is best to do it at the object level, so you'd want to do it as a child object of Invoice. Just remember to define a single, clear responsibility for each object as I discuss in Chapter 6 and that will help keep things managible.
The question I have is whether this "accounting information" is read-only or editable? From your description it certainly sounds like it could be read-only information that is used by the Invoice object in order to implement various business logic. In that case you might have some very clear responsibilities:
Invoice: Enter/edit valid invoice data
AccountingInfo: Provide read-only access to accounting parameters/settings
In this case it is absolutely valid for Invoice to have a "using" relationship (NOT parent-child) with AccountingInfo. In other words, the Invoice object, at the appropriate time, might just ask for the AccountingInfo object - which would be a read-only root object all by itself:
[NonSerialized][NotUndoable]
private AccountingInfo _acctInfo;
// ...
if (_acctInfo == null)
_acctInfo = AccountingInfo.GetInfo(supply params here);
To lazy load a child object you implement the object following the child template (MarkAsChild is called, and so forth), but you also implement a factory method (typically internal/Friend) and a DataPortal_Fetch() method. The data portal itself has no idea about root or child objects - it just routes calls to DataPortal_XYZ methods.
If I were you I'd carefully walk through the use case though, and identify sub use cases and the objects required by each. I have a suspicion that the accounting info object is not actually a child of Invoice, but rather is an editable root on its own, and that it is part of a sub use case within the overall "Create an Invoice" use case. I could be wrong, as I don't know your domain, but this is my guess.
Either that or you have two Invoice objects - the "Collect data" one and the "Processed data" one. In other words, I suspect that this is what happens:
I think what you have here are three objects: InvoiceCollector, InvoiceProcessor and Invoice - for steps 1, 2 and 3 respectively.
InvoiceCollector is probably not a root object as such. It is probably more like a non-persisting object as I just described to Barry here (http://forums.lhotka.net/forums/permalink/1417/1496/ShowThread.aspx#1496).
InvoiceProcessor is probably a CommandBase object that moves InvoiceCollector to the server and processes it there - then discards it, and creates an Invoice object based on the processed results. This Invoice object is then returned to the UI through InvoiceProcessor.
This allows step 3 to have an Invoice object that is post-processed, with your rules applied.
Hopefully this makes sense in some way.
Copyright (c) Marimer LLC