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。由于看起来您已经通过 ParentContainer
和 ChildContainer
管理依赖项组,我认为您不必使用程序集。
使用过Typhoon 的人可能更喜欢该功能。使用过其他register
/resolve
类型 DI 容器的人可能更喜欢自己组织容器结构。
2. func loaded(resolver: ResolverType) 方法的目的是什么?我应该保留解析器吗?会不会导致retain cycle?
在将所有程序集应用到容器后调用它,以执行在 Assembly
的 assemble
方法期间无法运行的操作。它被 Swinject 的系统调用,就像 UIKit 系统调用的UIViewController
的viewDidLoad
一样。 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 导致无法加载文件或程序集“...”或其依赖项之一。访问被拒绝