Targeted dependency injection at runtime with generics


First, let me introduce my current architecture (it's already there, so I have to rely on it)
I have an external objC framework VideoSDK that allows me to load and to show various video types (for the sake of it, let's say YoutubeVideo, DailymotionVideo, LocalVideo, each Video type being a totally separate objC object)

Now I created another framework (in SwiftUI) that allows me to load and show the videos from my objC framework.
In order to have a more typesafe yet flexible solution, I used a protocol based approach with some generics.

protocol VideoManager {
   associatedtype Video
   var video: Video { get }
   init(_: Video)
   func load()
   func show()
   var videoDelegate: Video.Delegate { get } // every lifecycle event related to the Video
   var videoPublisher: VideoPublisher<Video> { get } // the same as videoDelegate but with combine for TCA

Now I made some custom implementations of this protocol like

struct  YoutuveVideoManager: VideoManager {
   typealias Video = YoutubeVideo
   var video: YoutubeVideo
   var videoDelegate: YoutubeVideo.Delegate
   var videoPublisher: VideoPublisher<YoutubeVideo>

   init(_ video: YoutubeVideo) { = video

   func load() {
      video.delegate = videoDelegate

   func show() {

This allows me to create a SwiftUI view that only needs access to load(), show() and the delegate callbacks.
On top of that, I have a factory that returns a VideoManager from a construct (naïve code just to show you how it's basically handled)

enum VideoType {
   case youtube, dailymotion, local

struct VideoFactory {
   func videManager<V: VideoManager>(for videoType: VideoType) -> V {
      switch videoType {
         case .youtube: return YoutubeVideoManager()
         case .dailymotion: return DailymotionVideoManager()
         case .local: return LocalVideoManager()

So far so ggod....

Now I wanted to introduce some TCA to handle the behind-the-scene videos.
Since I can't just initialize my AppReducer with a runtime implementation of VideoManager, it seems that I need to inject this dependency into my reducer (I will also have to create a kind of AsyncStream ou related stuff to handle the delegate callback through the combine object like for the LiveAudioPlayer example.

But, at runtime, my View has no knowledge of the kind of implementation it is fed with (YoutubeVideoManager, DailyMotionVideoManager or LocalVideoManager ?). So it seems that I need to find a way to initialise my 'generic' reducer with a runtime copy of a VideoManager.

How can I achieve that ? I'm really stuck here :thinking: