Search code examples
c#dependency-injectionautofacstructuremap4

Can I override a list registration in StructureMap/Autofac?


For overriding/replacing type registrations both frameworks use the "last registration wins". For collections (multiple implementations of the same interface) however, in both frameworks the collection is added to, never completely overridden/replaced with a new collection:

For<IService>().Use<Service1>();
For<IService>().Use<Service2>();
GetInstance<IEnumerable<IService>>() == IEnumerable[Service1, Service2]

// Overriding in child container/profile or Autofac tenant
For<IService>().Use<Service3>();
GetInstance<IEnumerable<IService>>() == IEnumerable[Service1, Service2, Service3]

// Even if I use StructureMap's ClearAll
For<IService>().ClearAll().Use<Service3>();
GetInstance<IEnumerable<IService>>() == IEnumerable[Service1, Service2, Service3]

My expectation is that I should be able to use something to clear or replace the parent registration when it comes to multiple implementations (i.e. collections) so that I can keep a separate list of a particular service in the parent/global and the child/tenant.

(I know StructureMap is no longer maintained and I'm willing to switch to another framework).


Solution

  • It is not possible to remove registration from Autofac.

    Anyway I can see 3 workarounds :

    1. you can create a new ContainerBuilder and copy the required registration.

      See Is it possible to remove an existing registration from Autofac container builder?

    2. You can register your own IEnumerable<T>

      builder.Register(c => new IService[] { c.Resolve<Service1>() })
             .As<IEnumerable<IService>>(); 
      
    3. You can create your own IRegistrationSource for IEnumerable<T> and filter on the requested type