jrunestone
jrunestone

Reputation: 93

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).

Upvotes: 1

Views: 531

Answers (2)

Cyril Durand
Cyril Durand

Reputation: 16192

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

Upvotes: 1

Steven
Steven

Reputation: 172676

Simple Injector allows replacing the complete collection:

var container = new Container();

// Register NullLogger and SqlLogger as a collection of ILogger instances
container.Collection.Register<ILogger>(typeof(NullLogger), typeof(SqlLogger));

// Enable overriding registrations (without setting this, Simple Injector will throw)
container.Options.AllowOverridingRegistrations = true;

// Replace the complete collection of loggers with two different loggers
container.Collection.Register<ILogger>(typeof(ConsoleLogger), typeof(MailLogger));

Upvotes: 1

Related Questions