This allows task initialization to be moved out of ShellDispatcher where it does not belong, as tasks are similar to components. Updating parts of TaskCollection, as the Dispatcher is still required to be passed around.
This will help reduce the coupling between ShellDispatcher and other objects.
Since ShellDispatcher never directly uses or interacts with TaskCollection, it doesn't make much sense for it to have one. Instead shells will either get their own, or be passed one in.