Initialization logic has been completely overhauled. The previous
implementation was based on an approach that prioritized keeping the
composition root in the Program class. However, I wasn't happy with
this. CliFx inevitably wants to be the effective entry point to the
application. This means that the Program class should be as dumb as
possible.
The motivation for all this rework is the Recyclarr GUI. I need to be
able to share more initialization code between the projects.
Along with the initialization logic changes, I unintentionally
interleaved in another, completely unrelated refactoring. The IAppPaths
class now uses `IFileInfo` / `IDirectoryInfo` instead of `string` for
everything. This greatly simplified the implementation of that interface
and reduced dependencies and complexity across the code base. However,
those changes were vast and required rewriting/fixing a lot of unit
tests.
The goal is to separate initialization logic from command business
logic. Some initialization requires modifying the environment before we
instantiate many objects needed for implementing command behavior. If
those objects get instantiated, they will most likely already start
using files/directories/environment on the system and we can't modify
those while they're in use.