C Sharp - Custom Lazy Loading 3/22/2011 All C Sharp posts
If you're in a non ORM environment and have are thinking of building something custom to lazy-load data, here are a couple of useful classes and their intended implementation. Both of these classes were built to suite my needs and expect the lazy loading method to take the parent object as its only parameter.
Lazy<TParent, TChild>
public class Lazy<TParent, TChild>
{
public Lazy(Func<TParent, TChild> func, TParent parent)
{
_func = func;
_parent = parent;
}
bool _hasValue;
TChild _value;
TParent _parent;
Func<TParent, TChild> _func;
public TChild Value
{
get
{
if (!_hasValue)
{
_value = _func(_parent);
_hasValue = true;
}
return _value;
}
}
}
LazyList<TParent, TCollection>
public class LazyList<TParent, TCollection> : IList<TCollection>
{
public LazyList(Func<TParent, IList<TCollection>> func, TParent parent)
{
_func = func;
_parent = parent;
}
TParent _parent;
Func<TParent, IList<TCollection>> _func;
IList<TCollection> _items;
IList<TCollection> Items
{
get
{
if (_items == null)
_items = _func(_parent) ?? new List<TCollection>();
return _items;
}
}
#region IList<TCollection> Members
int IList<TCollection>.IndexOf(TCollection item)
{
return Items.IndexOf(item);
}
void IList<TCollection>.Insert(int index, TCollection item)
{
Items.Insert(index, item);
}
void IList<TCollection>.RemoveAt(int index)
{
Items.RemoveAt(index);
}
TCollection IList<TCollection>.this[int index]
{
get { return Items[index]; }
set { Items[index] = value; }
}
#endregion
#region ICollection<TCollection> Members
void ICollection<TCollection>.Add(TCollection item)
{
Items.Add(item);
}
void ICollection<TCollection>.Clear()
{
Items.Clear();
}
bool ICollection<TCollection>.Contains(TCollection item)
{
return Items.Contains(item);
}
void ICollection<TCollection>.CopyTo(TCollection[] array, int arrayIndex)
{
Items.CopyTo(array, arrayIndex);
}
int ICollection<TCollection>.Count
{
get { return Items.Count; }
}
bool ICollection<TCollection>.IsReadOnly
{
get { return Items.IsReadOnly; }
}
bool ICollection<TCollection>.Remove(TCollection item)
{
return Items.Remove(item);
}
#endregion
#region IEnumerable<TCollection> Members
IEnumerator<TCollection> IEnumerable<TCollection>.GetEnumerator()
{
return Items.GetEnumerator();
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
return Items.GetEnumerator();
}
#endregion
}
Usage
myObject.SomeLazy = new Lazy<MyObjectType, SomeLazyType>(GetSomeLazy, myObject);
myObject.SomeList = new LazyList<MyObjectType, OtherObjectType>(
SomeMethodThatTakes, myObject);