Thanks to @dot_NET_Junkie for pointing me to this article How *not* to inject services into entities
Here’s my version:
public interface IEntityLoader<T> where T : class { bool IsLoaded { get; } T Value { get; } }
////// This class has been designed to enable Lazy Loading within an Entity /// without the need for the Entity to hold a reference to the data service /// e.g. Repository or UnitOfWork /// ///public class EntityLoader : IEntityLoader where T : class { private object o; private T _entity; private Func _loader; /// /// this constructor is for direct value assignment /// /// private EntityLoader(T value) { _entity = value; _loader = null; } ////// this constructor is for lazy loading /// /// public EntityLoader(Funcloader) { _entity = null; _loader = loader; o = new object(); } public T Value { get { if (_loader != null) { lock (o) { if (_loader != null) { _entity = _loader(); _loader = null; } } } return _entity; } set { if (_loader != null) _loader = null; _entity = value; } } public bool IsLoaded { get { return _loader == null; } } public static implicit operator T(EntityLoader entityLoader) { return entityLoader.Value; } public static implicit operator EntityLoader (T value) { return new EntityLoader (value); } }
I’m going to give this a go later today. In Entity Framework I can subscribe to the ObjectContext.ObjectMaterialized Event and construct/insert the lazy loading references at this time. Currently I have a reference to the Container and the Repository within my Entities – both are generally considered an anti-pattern.