BackgroundMotion Code Sample
The BackgroundMotion community site and ASP.NET code sample that we worked with Microsoft to develop has gone live. w00t!
If you’re interested in ASP.NET you definitely want to check out the sample as it illustrates one approach to architecting .NET web apps. The architecture was really designed to facilitate rapid development so emphasizes things like testability etc. My personal highlights of the sample are:
- Use of a domain-driven design techniques. Repository and Unit of Work abstractions over LINQ to SQL
- Model-level validation using the Validation Block
- Dependency injection using Composite Web Block
- Using Lucene.NET to index a domain model
- Using MVP with declarative data-binding in the presentation layer
Let us know what you think.
Eager Loading
Alex has been thinking a bit about object eager-loading (prefetch) retrieval strategies recently.
The LINQ to SQL approach of using a Lambda is interesting and was the approach we used on BackgroundMotion:
Contribution contribution = Repository<Contribution>
.Find(1)
.Including(c => c.ContributionTags);What’s more interesting to me however is that now we have a way to refer to symbols in a type safe way. Useful for things like data binding etc. where we want to specify a property and where currently we have to use a string. That’s not to say that this Lambda syntax is optimal for this but what can you do? :-)
With respect to eager load strategies our new domain model/persistence framework LightSpeed has the notion of a “named aggregate” - aggregate being a term taken from Domain-driven design. Basically we use an attribute called EagerLoad at the association level in the model:
[EagerLoad(AggregateName="ContributionDetail")] public readonly EntityCollection<ContributionTag> _contributionTags = new EntityCollection<ContributionTag>();
Then we can specify an aggregate name as part of our query.
Query query = new Query(Entity.Attribute("Title").Like("A%")); query.AggregateName = "ContributionDetail"; IList<Contribution> contributions = Repository.Find<Contribution>(query);
The key point is that we are being explicit about naming the aggregates.
Fixing Leaky Repository Abstractions with LINQ
One of the issues with current implementations of the Repository pattern is that ORM specific details can leak into the Repository interface. Most commonly this takes the form of concrete ORM querying machinery such as Query Objects, Expressions or custom object query languages. This weakening of the Repository abstraction is undesirable because it can make it more difficult to use our Repositories in different ways. For example using a fake repository to speed up our unit tests.
Enter LINQ. With language-level support for building expressions, we can now shore up our Repository interface in a completely abstract way. Our query expressions are simply handed off to the appropriate LINQ-provider which does the heavy-lifting for us. Even better, normal collections can be queried using LINQ and so implementing trivial in-memory fake repositories is dead easy. We used this approach on BackgroundMotion and it worked pretty well. Here’s what some of the code looks like:
// our Repository contract... public interface IRepository<T> where T : IIdentifiable { int Count(); int Count(Expression<Func<T, bool>> expression); void Add(T entity); void Remove(T entity); void Save(T entity); T FindOne(int id); T FindOne(Expression<Func<T, bool>> expression); bool TryFindOne(Expression<Func<T, bool>> expression, out T entity); IList<T> FindAll(); IList<T> FindAll(Expression<Func<T, bool>> expression); IQueryable<T> Find(); IQueryable<T> Find(int id); IQueryable<T> Find(Expression<Func<T, bool>> expression); } // and this is how we used our real Repository implementation Repository<Contribution> .Find(c => c.ApprovedById == null); // or... Repository<Tag> .Find() .OrderBy(t => t.Value) .Take(Constants.PageSize) .ToList();
Using this approach we were able to implement a fake Repository that used simple collections internally and just worked.
Good times. :-)


