使用Storyboard时,如何对第一个屏幕的视图控制器进行依赖项注入? [英] How to do dependency injection for the view controller of the first screen when using storyboard ?

查看:90
本文介绍了使用Storyboard时,如何对第一个屏幕的视图控制器进行依赖项注入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

手动编写代码时,我们可以通过在 AppDelegate 中通过构造函数注入将依赖项注入rootViewController:

  UIViewController * vc = [[SomeViewController分配] initWithDependency:依赖项]; 
self.window.rootViewController = vc;

但是,在使用 Storyboard 时,我找不到注入依赖项的方法。将它们注入 awakeFromNib viewDidLoad 等似乎不合适。



是否可以注入它们?

解决方案

要正确进行依赖项注入,您需要做两件事:



1-在根视图控制器中注入数据。



这可以在如MarMass答案中所示的应用程序委托,或者如果您需要一些也适合文档应用程序的东西,则可以按照我在此处接受的答案中的建议进行操作:



(不要忘记选择器名称末尾的':')



这样,您可以保留视图控制器代码完全清除了控制器之间的关系。



我希望将所有segue动作保存在与故事板相同目录中的单个文件中。如果我更改情节提要,则更改了segue动作,而不是控制器...




When writing code manually, we could inject dependencies to rootViewController by constructor injection in AppDelegate:

UIViewController *vc = [[SomeViewController alloc] initWithDependency: dependency];
self.window.rootViewController = vc;

However, I can not find a way to inject dependencies when using Storyboard. It seems inappropriate to inject them in awakeFromNib or viewDidLoad etc.

Is that possible to inject them ?

解决方案

For doing dependency injection properly, you need 2 things :

1 - inject the data in your root view controller.

This can be done in the App delegate as shown in MarMass answer, or if you need something that also suits document applications, you can do it as I suggested in the accepted answer there : Can't use storyboard custom instantiated window controller

2 - you need to pass data from the root view controller to its descendants.

You will find many people saying "use prepareForSegue" for that. I really dislike using prepeareForSegue because it creates a hard dependency from the root view controller to its descendants, when I think each view controller should be kept independent.

You can't reuse your controllers in another Storyboard flow without modifying the view controller code (in that case prepareForSegue) again and again.

Plus, if you have many relationship, your prepareForSegue methods become a huge "case" code. Always an indicator that we can do better.

I suggest another method :

Create an extension to your view controller with an @IBSegueAction, and hook that @IBSegueAction to the segue view Interface Builder. This works both for transition segues and embedding segue.

extension FatherViewController {
    @IBSegueAction func injectToTextViewController(_ coder: NSCoder) -> NSViewController? {

        //  Create the destination view controller
        let destinationViewController = TextViewController(coder: coder)!

        //  Compute here the data to inject to the destination controller. As this is an extension of the father view controller, you have access to all its data
        destinationViewModel.data = self.data

        return destinationViewController
   }
}

(don't forget the ':' at the end of the selector name)

This way, you can keep your view controller code completely clean of thecontroller-to-controller relationships.

I like to keep all my segues actions in a single file that I put in the same directory as my storyboard. If I change the storyboard, I change the segue actions, not the controllers...

这篇关于使用Storyboard时,如何对第一个屏幕的视图控制器进行依赖项注入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆