1

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

Cyril Durand
  • 15,834
  • 5
  • 54
  • 62
jrunestone
  • 13
  • 3

2 Answers2

1

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));
Steven
  • 166,672
  • 24
  • 332
  • 435
  • Thank you Steven I actually started out with SI however in my project I need some form of child container or multitenancy support with an isolated scope (which to my knowledge isn't supported by SI) which is why I decided to try another framework. I really like SI's support for generics and the design decisions in general. I wasn't aware of the AllowOverridingRegistrations though, neat. – jrunestone Dec 05 '19 at 19:09
1

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

Community
  • 1
  • 1
Cyril Durand
  • 15,834
  • 5
  • 54
  • 62