Locking during cache population
What I don't like about your approach is that the lock objects are never removed from FooServiceCacheLocks, even when the object is removed from the cache.

One way to simplify your code would be to combine MemoryCache with Lazy: instances of Lazy are cheap (as long as you don't access its Value) so you can create more of them than needed. With that your code would look something like this:

public IEnumerable&lt;Foo&gt; GetFoosForBar(int barId)
{
    var newLazy = new Lazy&lt;IEnumerable&lt;Foo&gt;&gt;(
        () =&gt; this.ExplicitService.GetFoosForBar(barId));

    var lazyFromCache = (Lazy&lt;IEnumerable&lt;Foo&gt;&gt;)MemoryCache.Default.AddOrGetExisting(
        barId.ToString(), newLazy, DateTime.Now.AddMinutes(5));

    return (lazyFromCache ?? newLazy).Value;
}