Swinject 中不同 ViewController 的依赖注入不一致,post Swift 3.0 更新:为什么?
Dependency injection inconsistency in differing ViewControllers in Swinject, post Swift 3.0 update: why?
我正在注册一些 Swinject
singleton-with-a-small-s (.container) 服务:
defaultContainer.register( SomeService.self )
{
_ in SomeService()
}.inObjectScope( .container )
defaultContainer.register( AnotherService.self )
{
responder in AnotherService(
someService: responder.resolve( SomeService.self )!
)
}.inObjectScope( .container )
将它们注入到一些视图控制器中:
defaultContainer.registerForStoryboard( SomeViewController.self )
{
resolvable, viewController in
viewController.someService = resolvable.resolve( SomeService.self )
viewController.anotherService = resolvable.resolve( AnotherService.self )!
}
defaultContainer.registerForStoryboard( AnotherViewController.self )
{
resolvable, viewController in
viewController.someService = resolvable.resolve( SomeService.self )
viewController.anotherService = resolvable.resolve( AnotherService.self )!
}
然后这些视图控制器以两种不同的方式显示,SomeViewController
像这样:
DispatchQueue.main.async
{
self.performSegue( withIdentifier: "somePageSegue", sender: nil )
}
和AnotherViewController
像这样:
let anotherViewController = UIStoryboard(
name: "Main"
, bundle: nil
).instantiateViewController( withIdentifier: "anotherSegue" )
present( anotherViewController, animated: true, completion: nil )
SomeViewController
注入了它的服务,但不幸的是 AnotherViewController
没有。
这曾经在 Swinject
升级到 Swift 3.0 之前有效,但现在无效。请问这是为什么,需要改什么?
谢谢。
更新
不幸的是,我既不熟悉 Swinject
的底层代码库,也没有时间熟悉自己,但是深入挖掘表面下发生的事情,我发现了以下内容,希望对任何可能比我更了解它的人:
成功 VC DI:
// once into:
private func injectDependency(to viewController: UIViewController)
// then:
defaultContainer.registerForStoryboard( SomeViewController.self )
// then many times into:
public func _resolve<Service, Factory>(name: String?, option: ServiceKeyOptionType? = nil, invoker: (Factory) -> Service) -> Service?
失败 VC DI:
// repeatedly going from:
private func injectDependency(to viewController: UIViewController)
// to:
public func _resolve<Service, Factory>(name: String?, option: ServiceKeyOptionType? = nil, invoker: (Factory) -> Service) -> Service?
// and back again,
// then twice into:
public override func instantiateViewController(withIdentifier identifier: String) -> UIViewController
补充说明:
失败的 VC 是 TabBarController 中的 UIViewController,两者都已在标准 XCode 情节提要中布置。
为了调用 registerForStoryboard
,您需要从 SwinjectStoryboard
实例化给定的控制器,而不仅仅是 UIStoryboard
:
let anotherViewController = SwinjectStoryboard.create(name: "Main", bundle: nil)
.instantiateViewController(withIdentifier: "anotherSegue")
present(anotherViewController, animated: true, completion: nil)
事实证明这是一个错误,详细信息在这里:https://github.com/Swinject/Swinject/issues/177。目前正在修复。一旦我知道更多,我会报告。
更新
这显然是固定的。
我正在注册一些 Swinject
singleton-with-a-small-s (.container) 服务:
defaultContainer.register( SomeService.self )
{
_ in SomeService()
}.inObjectScope( .container )
defaultContainer.register( AnotherService.self )
{
responder in AnotherService(
someService: responder.resolve( SomeService.self )!
)
}.inObjectScope( .container )
将它们注入到一些视图控制器中:
defaultContainer.registerForStoryboard( SomeViewController.self )
{
resolvable, viewController in
viewController.someService = resolvable.resolve( SomeService.self )
viewController.anotherService = resolvable.resolve( AnotherService.self )!
}
defaultContainer.registerForStoryboard( AnotherViewController.self )
{
resolvable, viewController in
viewController.someService = resolvable.resolve( SomeService.self )
viewController.anotherService = resolvable.resolve( AnotherService.self )!
}
然后这些视图控制器以两种不同的方式显示,SomeViewController
像这样:
DispatchQueue.main.async
{
self.performSegue( withIdentifier: "somePageSegue", sender: nil )
}
和AnotherViewController
像这样:
let anotherViewController = UIStoryboard(
name: "Main"
, bundle: nil
).instantiateViewController( withIdentifier: "anotherSegue" )
present( anotherViewController, animated: true, completion: nil )
SomeViewController
注入了它的服务,但不幸的是 AnotherViewController
没有。
这曾经在 Swinject
升级到 Swift 3.0 之前有效,但现在无效。请问这是为什么,需要改什么?
谢谢。
更新
不幸的是,我既不熟悉 Swinject
的底层代码库,也没有时间熟悉自己,但是深入挖掘表面下发生的事情,我发现了以下内容,希望对任何可能比我更了解它的人:
成功 VC DI:
// once into:
private func injectDependency(to viewController: UIViewController)
// then:
defaultContainer.registerForStoryboard( SomeViewController.self )
// then many times into:
public func _resolve<Service, Factory>(name: String?, option: ServiceKeyOptionType? = nil, invoker: (Factory) -> Service) -> Service?
失败 VC DI:
// repeatedly going from:
private func injectDependency(to viewController: UIViewController)
// to:
public func _resolve<Service, Factory>(name: String?, option: ServiceKeyOptionType? = nil, invoker: (Factory) -> Service) -> Service?
// and back again,
// then twice into:
public override func instantiateViewController(withIdentifier identifier: String) -> UIViewController
补充说明:
失败的 VC 是 TabBarController 中的 UIViewController,两者都已在标准 XCode 情节提要中布置。
为了调用 registerForStoryboard
,您需要从 SwinjectStoryboard
实例化给定的控制器,而不仅仅是 UIStoryboard
:
let anotherViewController = SwinjectStoryboard.create(name: "Main", bundle: nil)
.instantiateViewController(withIdentifier: "anotherSegue")
present(anotherViewController, animated: true, completion: nil)
事实证明这是一个错误,详细信息在这里:https://github.com/Swinject/Swinject/issues/177。目前正在修复。一旦我知道更多,我会报告。
更新
这显然是固定的。