Joining Microsoft

Posted by Andrew on September 02, 2008

I’m very excited to announce that, starting November, I’ll be working as a dev within the SQL Server DP group - specifically on the .

The position is based in Redmond but I missed the H1B this year and so we’re heading up to the . By all accounts, Vancouver is a great place to live and my wife and I are looking forward to the change of scene - We both ski too and are stoked about having one of the right on our doorstep :-)

The decision to leave , the company I co-founded was, of course, not taken lightly. I’m highly proud of what I helped create there - especially LightSpeed (my baby originally). I will particularly miss the variety of discussion that occurs in a small, developer-led shop like Mindscape. In my opinion, starting a company is a truly worthwhile experience because it forces you to consider all those things other than the code - You quickly learn that it’s those things that matter more.

That said, working for a company like Microsoft gives you the opportunity to touch many, many people’s lives…and, hopefully, make them just a little bit better.

BackgroundMotion Code Sample

Posted by Andrew on June 19, 2007

The community site and ASP.NET 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.

Fixing Leaky Repository Abstractions with LINQ

Posted by Andrew on April 28, 2007

One of the issues with current implementations of the 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. :-)

Dynamic Linq Queries - Contains Operator

Posted by Andrew on April 24, 2007

Ayende just about dynamic LINQ queries and how not to write them.

On BackgroundMotion we were using Linq to SQL and needed the Contains operator. Unfortunately, on the CTP we were using the wasn’t implemented by the Linq to SQL provider. Happily however, we were able to emulate it by dynamically building the required query. Here is the code:

public static class LinqContainsPredicateBuilder
{
  public static Expression<Func<T, bool>> Build<T, S>(ICollection<S> collection, string targetProperty)
  {
    Invariant.ArgumentNotEmpty(collection, "collection");
    Invariant.ArgumentNotEmpty(targetProperty, "targetProperty");
 
    Expression completeExpression = null;
    ParameterExpression parameterExpression = Expression.Parameter(typeof(T), "t");
 
    foreach (S item in collection)
    {
      Expression nextExpression = Expression.EQ
        (
        Expression.Property(parameterExpression, typeof(T).GetProperty(targetProperty)),
        Expression.Constant(item)
        );
 
      completeExpression = (completeExpression != null)
        ? Expression.OrElse(completeExpression, nextExpression)
        : nextExpression;
    }
 
    return (Expression<Func<T, bool>>)QueryExpression.Lambda(completeExpression, parameterExpression);
  }
}

For example, let’s say we are interested in finding all the Tag objects in the repository corresponding to a list of tags entered by a user. We could do this like so:

IList<string> candidateTags = new List<string>();
 
candidateTags.Add("Foo");
candidateTags.Add("Bar");
candidateTags.Add("Baz");
 
Expression<Func<T, bool>> expr
  = LinqContainsPredicateBuilder.Build<Tag, string>(candidateTags , "Value");
 
// now use the expression in a LINQ query...

This code will return any Tag objects that have a Value property matching any of the elements in the candidateTags list.

Being able to do this kind of thing is powerful and compelling feature of LINQ.

Enterprise Library 3.0 December 2006 CTP Released

Posted by Andrew on January 08, 2007

The new version includes among other things:

  • Validation Application Block
  • Data Access Application Block Enhancements (mainly SQL Server Compact Edition support)
  • Configuration Tool Enhancements (VS integration, encryption support)
  • Application Block Software Factory
  • Strong Naming Guidance Package

Get the CTP .