Swinject:迁移到程序集

Posted

技术标签:

【中文标题】Swinject:迁移到程序集【英文标题】:Swinject: migrating to assemblies 【发布时间】:2016-01-11 07:05:54 【问题描述】:

我在我的项目中为 DI 使用了很棒的 Swinject,但我在没有程序集的情况下使用它(当我开始使用 Swinject 时,还没有程序集)。

我目前使用Containers的模式是:

class ParentContainer 

    private let container: Container

    init(parentContainer: Container?) 
        container = Container(parent: parentContainer)

        container.register....
    

    func myTopLevelController() -> MyTopController 
        let controller = container.resolve....
        controller.container = self // controller holds its container
        return controller
    

    func childContainer() -> ChildContainer 
        return ChildContainer(parentContainer: container)
    




class ChildContainer 

    private let container: Container

    init(parentContainer: Container?) 
    ....

使用该配置:

容器只要它们需要存活就可以存活(唯一持有对它们的引用的实体 - VC,可以使用依赖项) 我可以停止使用/切换 DI 框架并替换 Container,即使是手动构建(我的代码不知道任何框架),因为我的代码调用:let topController = ParentContainer().myTopLevelController()

现在我正在尝试申请Assembly。据我了解,my 容器现在将符合AssemblyType 协议。但我有些困惑:

    我应该通过程序集解决实例,而不是通过容器吗? func loaded(resolver: ResolverType) 方法的目的是什么?我应该保留解析器吗?会不会导致retain cycle? 我希望拥有 TopLevelAssembly,但仍将容器用于叶实体。是否可以将 Assembly 作为容器的父级传递?或者还有其他方法可以实现吗?

【问题讨论】:

【参考方案1】:

1.我应该通过组装而不是通过容器来解决实例吗?

是否使用组装功能取决于您。使用to manage grouping of dependencies。由于看起来您已经通过 ParentContainerChildContainer 管理依赖项组,我认为您不必使用程序集。

使用过Typhoon 的人可能更喜欢该功能。使用过其他register/resolve 类型 DI 容器的人可能更喜欢自己组织容器结构。

2. func loaded(resolver: ResolverType) 方法的目的是什么?我应该保留解析器吗?会不会导致retain cycle?

在将所有程序集应用到容器后调用它,以执行在 Assemblyassemble 方法期间无法运行的操作。它被 Swinject 的系统调用,就像 UIKit 系统调用的UIViewControllerviewDidLoad 一样。 The documentation about loaded 或 a unit test 可能有助于您理解 loaded 功能。

您不应该存储resolver 参数。 (实际上我没有看到用例来存储它,因为Assembler 不保留对程序集的引用,这些引用将在您实例化Assembler 后释放。即使您存储它,也不会导致保留循环。)

3.我想要 TopLevelAssembly,但仍将容器用于叶实体。是否可以将 Assembly 作为容器的父级传递?或者还有其他方法可以实现吗?

我没有听懂您关于 TopLevelAssembly 和叶实体的上下文。如果您添加更多详细信息,我稍后会更新我的答案。

以下是问题部分的一些 cmets:您不能传递 Assembly 实例,因为 Container 的初始化程序是 init(parent: Container? = nil),它采用 Container 的实例。实现它的另一种方法可能是将顶层保持为Container。 (或者我必须更新 Swinject 以支持该场景。)

我的回答可能并不完美,但我希望它能帮助你实现服务定位器模式。

【讨论】:

感谢您的回答和您的库!只是为了对 3 做一些澄清。实际上,我的方案比上面描述的更复杂。假设我有 AppContainer -> UserContainer -> ControllerContainer。第一个包含所有系统范围的服务(api、db 等),第二个存储与用户相关的数据,第三个知道如何构建特定的控制器。我不希望将所有数据都转储到 AppContrainer 中(因为它可能很复杂),并且我认为 Assembly 是一个水平分组,但要保持我的数据垂直结构相同。有可能吗? 感谢您提供有关水平和垂直分组的上下文。到目前为止,Swinject 的程序集不支持混合水平和垂直分组。 Assembler 的初始化器只能采用 Container 类型。如果我添加一个初始化程序来获取父级Assembler,则可以添加该功能,但我必须调查对现有代码的影响。我从你的评论中得到了足够的细节,所以我们不需要 Skype 聊天。为了您的隐私,您可以删除您的 Skype ID。

以上是关于Swinject:迁移到程序集的主要内容,如果未能解决你的问题,请参考以下文章

从 packages.config 迁移到 PackageReferences 导致无法加载文件或程序集“...”或其依赖项之一。访问被拒绝

使用不同的程序集添加迁移

升级程序集时,在隔离存储中迁移文件的最佳方法是啥?

添加迁移导致“无法加载程序集”错误

Java程序员学深度学习 DJL上手9 在CIFAR-10数据集使用风格迁移学习

Java程序员学深度学习 DJL上手9 在CIFAR-10数据集使用风格迁移学习