Autofac delegate factory using func<>

Narayan Akhade picture Narayan Akhade · Mar 14, 2013 · Viewed 12.6k times · Source

I am trying to understand the delegate factory pattern with Autofac. I know how to implement factory using IIndex<> with Keyed() registration, which is explained nicely in here: Configuring an Autofac delegate factory that's defined on an abstract class

I would like to know if I can create a factory using Func<>, and how would I do the registrations for the following sample:

public enum Service
{
   Foo,
   Bar
}

public interface FooService : IService 
{
   ServiceMethod();
}

public interface BarService : IService 
{
   ServiceMethod();
}

public class FooBarClient
{
   private readonly IService service;

   public FooBarClient(Func<Service, IService> service)
   {
      this.service = service(Service.Foo);
   }

   public void Process()
   {
      service.ServiceMethod(); // call the foo service.
   }
}

Answer

nemesv picture nemesv · Mar 15, 2013

Autofac cannot construct this Func<Service, IService> for you which lets you return different types based on a parameter. This is what IIndex<> is for.

However if you don't want/cannot use IIndex<> you can create this factory function with the help of the Keyed or Named and register your factory in the container:

var builder = new ContainerBuilder();
builder.RegisterType<FooBarClient>().AsSelf();
builder.RegisterType<FooService>().Keyed<IService>(Service.Foo);
builder.RegisterType<BarService>().Keyed<IService>(Service.Bar);

builder.Register<Func<Service, IService>>(c => 
{
    var context = c.Resolve<IComponentContext>();
    return s => context.ResolveKeyed<IService>(s);
});