I'm contributing to an open source project that is looking to support multiple containers for its internal services. One of the requirements for supported containers is that order of registration matters. So, if several implementations of an interface are registered in a particular order, when a list of those services is resolved, the implementations should be returned in the same order they were registered.
var builder = new ContainerBuilder();
builder.RegisterType<PreferredService>().As<IService>();
builder.RegisterType<AlternativeService>().As<IService>();
builder.RegisterType<AdditionalService>().As<IService>();
...
// Get the first (preferred) implementation of IService.
var possibleServices = container.Resolve<IEnumerable<IService>>();
IService idealServiceImplementation = possibleServices.FirstOrDefault();
My testing shows that Autofac returns the services is reverse order. Is this always the case? Can I trust they will resolve in reverse order every time? Will this behavior be consistent even if I register some of the later services after other registrations for different interfaces? Can I intercept implicit calls to Resolve for lists?
Is there a way to instruct Autofac that registration order matters?
Autofac registrations are always "last registration wins" unless you use PreserveExistingDefaults()
. A quick look into the implementation shows that registrations are stored as a linked list where the default behavior adds to the beginning and PreserveExistingDefaults()
adds to the end. Resolving a single service gets you the first item in the list. Resolving enumerable gets you that order. I'm not sure if that behavior is guaranteed to never change.
If it were me, I'd depend on the current behavior, but write an automated test that will fail if the behavior changes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With