1

I would like to pass an object that conforms to some protocol, and resolve its type for allocation with Swinject framwork (By dependency injection).

protocol IViewModelAware {
    typealias T
    var viewModel : T { get set }
}


class ViewAndViewModelCreator {
    var container : Container

    init(container : Container) {
        self.container = container
    }

    func resolveViewModel<T : IViewModelAware>(controller : T) {
        let mirror = Mirror(reflecting: controller.viewModel)
        let viewModelClassType = mirror.subjectType
        let viewModel = self.container.resolve(viewModelClassType.self) // This line shows error
        controller.viewModel = viewModel
    }

}

Error: Cannot invoke 'resolve' with an argument list of type '(Any.Type)'

How do I get the Class from an object that confirms to protocol, maybe there is another option except reflection?

Yoichi Tagaya
  • 4,547
  • 2
  • 27
  • 38
MCMatan
  • 8,623
  • 6
  • 46
  • 85
  • 1
    You can get the type of the view model class by `controller.viewModel.dynamicType`, which can be passed to `container.resolve` method. What you would like to do is switching `viewModel` instances? Because `viewModel` property is not optional, the code changes the existing `controller.viewModel` instance to a new one resolved by the `container`. I will be able to answer to your question with the context what you would like to achieve. – Yoichi Tagaya Dec 16 '15 at 09:15
  • Thank you @Yoichi this is exactly what I needed. And it didn't have to be optional since it gets injected on Allocation (: – MCMatan Dec 16 '15 at 11:44
  • That's good to hear you it was what you needed. I wrote an official answer to tell the usage of `dynamicType`. – Yoichi Tagaya Dec 16 '15 at 17:13

1 Answers1

0

You can get the type of the view model class from its instance by controller.viewModel.dynamicType:

func resolveViewModel<T : IViewModelAware>(controller : T) {
    let viewModel = container.resolve(controller.viewModel.dynamicType)
    // ...
}
Yoichi Tagaya
  • 4,547
  • 2
  • 27
  • 38