You can use keyed/named services and IIndex to do it, there's a good entry on the autofac page here.
Here's a quick example of what it'd look like:
public class Factory
{
private readonly IIndex<string, ISearchService> _index;
public Factory(IIndex<string, ISearchService> index)
{
_index = index;
}
public ISearchService Resolve(string id)
{
return _index[id];
}
}
// Registrations
var builder = new ContainerBuilder();
builder.Register<ASearchService>(c => new ASearchService()).Keyed<ISearchService>("A");
builder.Register<BSearchService>(c => new BSearchService()).Keyed<ISearchService>("B");
builder.Register<Factory>(c => new Factory(c.Resolve<IIndex<string, ISearchService>>()));
// as per autofac's page linked above, autofac automatically implements IIndex types
// Usage
var aSearchService = fact.Resolve("A");
EDIT: I thought we could do better than this, so here are a couple of extension methods to obviate the creation of an explicit factory class:
public delegate TReturn AutoFactoryDelegate<TParam, TReturn>(TParam param);
public class AutoFactory<TParam, TReturn>
{
private readonly IIndex<TParam, TReturn> _index;
public AutoFactory(IIndex<TParam, TReturn> index)
{
_index = index;
}
public TReturn Resolve(TParam param)
{
return _index[param];
}
}
public delegate TReturn AutoFactoryDelegate<TParam, TReturn>(TParam param);
public static class AutofacExtensions
{
public static void RegisterAutoFactoryDelegate<TParam, TReturn>(this ContainerBuilder builder)
{
builder.Register(c => new AutoFactory<TParam, TReturn>(c.Resolve<IIndex<TParam, TReturn>>()));
builder.Register<AutoFactoryDelegate<TParam, TReturn>>(c =>
{
var fact = c.Resolve<AutoFactory<TParam, TReturn>>();
return fact.Resolve;
});
}
}
// Registration
var builder = new ContainerBuilder();
builder.Register<ASearchService>(c => new ASearchService()).Keyed<ISearchService>("A");
builder.Register<BSearchService>(c => new BSearchService()).Keyed<ISearchService>("B");
builder.RegisterAutoFactoryDelegate<string, ISearchService>();
// Usage
// fact is an AutoFactoryDelegate<string, ISearchService>
var aSearchService = fact("A");
EDIT 2: After looking at this again, we don't need the Factory classes, since IIndex is in effect the factory already. This leads to quite a simplification from the implementation side:
public static void RegisterAutoFactoryDelegate<TParam, TReturn>(this ContainerBuilder builder)
{
builder.Register(c =>
{
var iindex = c.Resolve<IIndex<TParam, TReturn>>();
return (Func<TParam, TReturn>) (id => iindex[id]);
});
}
// Registration
var builder = new ContainerBuilder();
builder.Register<ASearchService>(c => new ASearchService()).Keyed<ISearchService>("A");
builder.Register<BSearchService>(c => new BSearchService()).Keyed<ISearchService>("B");
builder.RegisterAutoFactoryDelegate<string, ISearchService>();
// Usage
// fact is an Func<string, ISearchService>
var aSearchService = fact("A");