Hey, I've been searching around for a solution to a tricky problem we're having with our code base.
To start, our code resembles the following:
class User
{
int id;
int accountId;
Account account
{
get { return Account.Get(accountId); }
}
}
class Account
{
int accountId;
OnlinePresence Presence
{
get { return OnlinePresence.Get(accountId); }
}
public static Account Get(int accountId)
{
// hits a database and gets back our object.
}
}
class OnlinePresence
{
int accountId;
bool isOnline;
public static OnlinePresence Get(int accountId)
{
// hits a database and gets back our object.
}
}
What we're often doing in our code is trying to access the account Presence of a user by doing
var presence = user.Account.Presence;
The problem with this is that this is actually making two requests to the database. One to get the Account object, and then one to get the Presence object. We could easily knock this down to one request if we did the following :
var presence = UserPresence.Get(user.id);
This works, but sort of requires developers to have an understanding of the UserPresence class/methods that would be nice to eliminate.
I've thought of a couple of cool ways to be able to handle this problem, and was wondering if anyone knows if these are possible, if there are other ways of handling this, or if we just need to think more as we're coding and do the UserPresence.Get instead of using properties.
Overload nested accessors. It would be cool if inside the User class I could write some sort of "extension" that would say "any time a User object's Account property's Presence object is being accessed, do this instead".
Overload the . operator with knowledge of what comes after. If I could somehow overload the . operator only in situations where the object on the right is also being "dotted" it would be great.
Both of these seem like things that could be handled at compile time, but perhaps I'm missing something (would reflection make this difficult?). Am I looking at things completely incorrectly? Is there a way of enforcing this that removes the burden from the user of the business logic?
Thanks! Tim