I have what could be seen as a bizarre hybrid of IQueryable<T>
and IList<T>
collections of domain objects passed up my application stack. I'm trying to maintain as much of the 'late querying' or 'lazy loading' as possible. I do this in two ways:
IQueryable<T>
s through by repositories and to my app layer.IList<T>
s but where certain elements in the object/aggregate graph are 'chained' with delegates so as to defer their loading. Sometimes even the delegate contents rely on IQueryable<T>
sources and the DataContext
are injected.This works for me so far.
What is blindingly difficult is proving that this design actually works. Ie. If i defeat the 'lazy' part somewhere and my evaluation/execution happens early then the whole thing is a waste of time. I'd like to be able to TDD this somehow.
I don't know a lot about delegates or thread safety as it applies to delegates acting on the same source. I'd like to be able to mock the DataContext
and somehow trace both methods of deferring (IQueryable<T>
's SQL and the delegates) the loading so that i can have tests that prove that both functions are working at different levels/layers of the app/stack.
As it's crucial that the deferring works for the design to be of any value, i'd like to see tests fail when i break the design at a given level (separate from the live implementation). Is this possible?
At morelinq, we have a so called "breaking sequence" to test that. Basically, it is an enumerator that will throw an exception whenever it is enumerated.
It can be as easy as:
internal sealed class BreakingSequence<T> : IEnumerable<T>
{
public IEnumerator<T> GetEnumerator()
{
throw new InvalidOperationException();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
A test for it looks like this:
[Test]
public void XyzIsLazy()
{
var source = BreakingSequence<EntityClass>().AsQueryable();
// inject it as your query source wherever appropriate
var query = source.Where(x=> true);
// does not throw, where does not enumerate the sequence
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With