使用Swinject时如何将参数传递给resolve方法?

时间:2016-06-11 19:11:35

标签: ios swift dependency-injection swinject

我有一个测试项目,我试图将参数传递给Swinject项目中的resolve方法。

以下是我的Swinject故事板扩展文件中包含的示例。

import Swinject

extension SwinjectStoryboard {

    class func setup() {

        let mainDm = MainDM()

        defaultContainer.register(MainDM.self) { _ in
            mainDm
        }

        defaultContainer.registerForStoryboard(ViewController.self) { r, c in
            c.dm = r.resolve(MainDM.self)
            c.container = defaultContainer

        }


        defaultContainer.register(GetMessageAction.self) { _, delegate in
            GetMessageAction(dm:mainDm, delegate: delegate)
        }

    }

}

在我的ViewController中我正在尝试执行以下操作来解决GetMessageAction

@IBOutlet weak var myText: UILabel!

    var dm:MainDM!
    var container:Container!

    override func viewDidLoad() {
        super.viewDidLoad()

        NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(3), target: self, selector: #selector(ViewController.getMessage), userInfo: nil, repeats: false)

    }

    func getMessage() {

        let action:GetMessageAction? = container.resolve(GetMessageAction.self, argument: self)!
        action?.execute()

    }

当我的getMessage函数运行时,我收到以下消息

  

致命错误:在解包可选值时意外发现nil

3 个答案:

答案 0 :(得分:2)

由于使用参数进行解析取决于完全匹配的参数类型,因此需要向下转换传递的对象:

GetMessageActionDelegate

假设GetMessageAction(dm:delegate:)是构造函数qemu-img convert -f qcow2 myImage.qcow2 -O vmdk myNewImage.vmdk 中传递的委托类型。

答案 1 :(得分:1)

您在Storyboard 中创建的ViewController的swift文件必须声明init(NSCoder),实际上在README.md中没有提及,我正在考虑打开一个有关此问题的问题...

   required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

您可以查看我的open source project using exactly this technique,我正在使用extension of SwinjectStoryboard here设置相关性,例如LoadingDataVC

extension SwinjectStoryboard {
    class func setup() {

        defaultContainer.register(HTTPClientProtocol.self) { _ in
            HTTPClient()
        }.inObjectScope(.Container)

        defaultContainer.register(APIClientProtocol.self) { r in
            APIClient(
                httpClient: r.resolve(HTTPClientProtocol.self)!
            )
        }.inObjectScope(.Container)

        defaultContainer.register(ImagePrefetcherProtocol.self) { _ in
            ImagePrefetcher()
        }.inObjectScope(.Container)

        defaultContainer.registerForStoryboard(GameVC.self) { r, c in
            c.imagePrefetcher = r.resolve(ImagePrefetcherProtocol.self)
        }

        defaultContainer.registerForStoryboard(LoadingDataVC.self) { r, c in
            c.apiClient = r.resolve(APIClientProtocol.self)
            c.imagePrefetcher = r.resolve(ImagePrefetcherProtocol.self)
        }
    }
}

一旦你有了必需的init,它应该可以工作! :)

答案 2 :(得分:0)

使用故事板的以下任一方法来获取registerForStoryboard注册的视图控制器。

  • instantiateViewControllerWithIdentifier
  • instantiateInitialViewController

https://github.com/Swinject/Swinject/blob/v1/Documentation/Storyboard.md https://github.com/Swinject/SwinjectStoryboard/issues/5