I'm neither familiar with that particular feature of Autofac nor the code base to which you refer, but some DI Containers support automatic generation of functions. After all, a function (or delegate) is just an anonymous interface; it's another way to model polymorphism.
A delegate with the type Func<ICurrencyPair, SpotTileSubscriptionMode, ISpotTileViewModel> is a function that will return an ISpotTileViewModel object if you supply an ICurrencyPair and a SpotTileSubscriptionMode. That's isomorphic to an interface like this:
public interface ISpotTileViewModelFactory
{
ISpotTileViewModel Create(ICurrencyPair pair, SpotTileSubscriptionMode mode);
}
Some DI Containers can autogenerate such factory interfaces as well. The algorithm goes something like this:
Keep in mind that at the heart of a DI Container is a table of mappings from polymorphic types to concrete types. For instance, the interface ISpotTileViewModel is mapped to a concrete type. Skimming the GitHub repository for the code base in question, I guess that the SpotTileViewModel class is the concrete type paired with ISpotTileViewModel.
The SpotTileViewModel class has one constructor. Thus, in order to be able to create an instance of it, the DI Container must analyse the constructor to figure out how to invoke it. It looks like this:
public SpotTileViewModel(
ICurrencyPair currencyPair,
SpotTileSubscriptionMode spotTileSubscriptionMode,
Func<ICurrencyPair, SpotTileSubscriptionMode, ISpotTileViewModel, ISpotTilePricingViewModel> pricingFactory,
Func<ITrade, ISpotTileViewModel, ISpotTileAffirmationViewModel> affirmationFactory,
Func<string, ISpotTileViewModel, ISpotTileErrorViewModel> errorFactory,
Func<ISpotTileConfigViewModel> configFactory)
It looks like a bit of a mouthful, but there's the ICurrencyPair and SpotTileSubscriptionMode, as well as four other functions.
The DI Container must now figure out how it can (if possible) create each of those six constructor arguments. It proceeds recursively through its table of mappings until it figures it out or has to give up. This process is what Steven van Deursen and I call Auto-Wiring in DIPPP.
My guess is that the DI Container has mappings for most of the polymorphic types in play here: ISpotTileAffirmationViewModel, ISpotTileErrorViewModel, and so on. Possible exceptions (but I'm speculating here) are exactly ICurrencyPair and SpotTileSubscriptionMode. But then, if you supply those two missing pieces, the DI Container knows how to map all the other pieces of the puzzle, and via Reflection Emit, it's able to 'code at run time' a function with the type Func<ICurrencyPair, SpotTileSubscriptionMode, ISpotTileViewModel>.