During this port, a home brew Inversion of Control (IoC) was created. This used the service locator (SL) pattern - basically, you ask it for an interface/type/service and it returns to you one that was registered to the system. Based off the framework's built-in IServiceProvider class. Now, this class doesn't do a whole lot, basically just provides a GetService(Type) method
There are many articles on pros and cons of DI vs SL supporting one or the other. But, I believe today's view is that SL is an anti-pattern (one example, Wikipedia page) because it hides you from knowing what dependencies are needed by the class, and hopefully they are registered with the system properly when calling the class. Although, pretty much all IoC's supporting injection also support manually resolving a reference - some times, you just have to do things not pretty 😀.
With the SL system in our app, I've found that Unit Testing is always extremely very tedious, and error prone. Partly because of the design of our system, also because you do not know what dependencies all the classes require - so mocking them is error prone. I can say passing all needed interfaces as part of a constructor certainly makes unit test setup easier. And during actual application runtime, have the IoC system inject all the services and manage lifetimes of shared resources is great.
So, my first goal was to find a modern, open source (having code is great when a tech becomes no longer popular/supported) IoC/DI platform for .Net. My second goal, was being able to have both the existing SL and the new DI system peacefully coexist. Needed to not break thousands of lines of code leading to runtime crashes trying to resolve dependencies.
After a bit of research, settled on Autofac. It had nice syntax, plenty of flexibility, and checked all the boxes.