I have a class, let's call it SomeClass. It has an initializer that takes in a view controller; except I have added an arbitrary protocol that my view controllers implement to abstract things away so I can test SomeClass. So the initializer looks like:
init(viewController: ViewControllerType)
All my viewcontrollers implement ViewControllerType.
I want to register SomeClass with Swinject and then pass the view controller into it as an argument, so I did:
container.register(SomeClass.self) {
r, viewController in
return SomeClass(viewController: viewController)
}
Only, Swinject has taken the ViewControllerType and doesn't see that having been registered. It only sees concrete view controllers being registered I guess?
What I can do to fix this?
Hi @gbrhaz,
please add the code where you are resolveing SomeClass - It is hard to tell what exactly is the problem only from register method.
Thanks 馃槈
Sure:
container.registerForStoryboard(ConcreteViewController.self) {
r, controller in
controller.someClass = r.resolve(SomeClass.self, argument: controller)!
}
In this code compiler would be unable to infer the type of controller variable - you need to explicitly specify it, e.g.
container.register(ConcreteViewController.self) { (r, controller: ViewControllerType) in
Controller(someClass: r.resolve(SomeClass.self, argument: controller)!
}
Seems to be inferring it just fine. The problem is a runtime issue, not a compiler issue.
@jakubvano Could you please help me understand my situation: I am not using storyboards and just trying to register some Service with argument. But resolve with argument always return nil.
This is a bug or I am just doing something wrong?
My code below:
// func assemble(container: Container)
var model: Hero?
container.register(ProtocolOne.self) { (r, hero: Hero) in
model = hero
let vc = ViewController(withHero: hero)
let helper = r.resolve(ProtocolTwo.self)!
vc.helper = helper
return vc
}
container.register(ProtocolTwo.self) { _ in
Helper()
}
.initCompleted { (r, two) in
let helper = two as? Helper
helper!.controller = r.resolve(ProtocolOne.self, argument: model) // always nil
}
// Usage:
assembler?.resolver.resolve(ProtocolOne.self, argument: Character(name: "Alex"))
@gbrhaz Sorry, I mistook registerForStoryboard for register method - A it stands, you need to explicitly upcast controller (for more info see docs):
controller.someClass = r.resolve(SomeClass.self, argument: controller as ViewControllerType)!
@siggb r.resolve(ProtocolOne.self, argument: model) is passing argument of type Hero?, while your register methods expecs argument of type Hero. One way to solve this would be
r.resolve(ProtocolOne.self, argument: model!)
@jakubvano That fixed it. Thanks, I did see something with the registration key, it just didn't click :)
Glad to help 馃槃 v1.1.5 will include logging of resolution failure (#168) which should help with debugging issues like these.
Most helpful comment
@siggb
r.resolve(ProtocolOne.self, argument: model)is passing argument of typeHero?, while yourregistermethods expecs argument of typeHero. One way to solve this would be