using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.Common; namespace Marr.Data { public interface ILazyLoaded : ICloneable { void Prepare(Func dbCreator, object parent); void LazyLoad(); } /// /// Allows a field to be lazy loaded. /// /// public class LazyLoaded : ILazyLoaded { protected TChild _child; protected bool _isLoaded; public LazyLoaded() { } public LazyLoaded(TChild val) { _child = val; _isLoaded = true; } public TChild Value { get { LazyLoad(); return _child; } } public virtual void Prepare(Func dbCreator, object parent) { } public virtual void LazyLoad() { } public static implicit operator LazyLoaded(TChild val) { return new LazyLoaded(val); } public static implicit operator TChild(LazyLoaded lazy) { return lazy.Value; } public object Clone() { return this.MemberwiseClone(); } } /// /// This is the lazy loading proxy. /// /// The parent entity that contains the lazy loaded entity. /// The child entity that is being lazy loaded. internal class LazyLoaded : LazyLoaded { private TParent _parent; private Func _dbCreator; private readonly Func _query; private readonly Func _condition; internal LazyLoaded(Func query, Func condition = null) { _query = query; _condition = condition; } public LazyLoaded(TChild val) : base(val) { _child = val; _isLoaded = true; } /// /// The second part of the initialization happens when the entity is being built. /// /// Knows how to instantiate a new IDataMapper. /// The parent entity. public override void Prepare(Func dbCreator, object parent) { _dbCreator = dbCreator; _parent = (TParent)parent; } public bool IsLoaded { get { return _isLoaded; } } public override void LazyLoad() { if (!_isLoaded) { if (_condition != null && _condition(_parent)) { using (IDataMapper db = _dbCreator()) { _child = _query(db, _parent); } } _child = default(TChild); _isLoaded = true; } } public static implicit operator LazyLoaded(TChild val) { return new LazyLoaded(val); } public static implicit operator TChild(LazyLoaded lazy) { return lazy.Value; } } }