Swinject:迁移到程序集
Swinject: migrating to assemblies
我在我的项目中使用很棒的 Swinject 作为 DI,但我在没有程序集的情况下使用它(当我开始使用 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,可以使用依赖项)
- 即使手动构建,我也可以停止 using/switch DI 框架并替换
Container
(我的代码不知道任何框架),因为我的代码调用:let topController = ParentContainer().myTopLevelController()
现在我正在尝试申请 Assembly
。据我所知,my 容器现在将符合 AssemblyType
协议。但是我有些困惑:
- 我应该通过程序集而不是通过容器来解析实例吗?
func loaded(resolver: ResolverType)
方法的目的是什么?我应该保留解析器吗?会导致retain cycle吗?
- 我想要 TopLevelAssembly,但仍将容器用于叶实体。是否可以将 Assembly 作为容器的父级传递?或者还有其他方法可以实现吗?
1.我应该通过程序集而不是容器来解析实例吗?
是否使用汇编功能由您决定。它被使用 to manage grouping of dependencies。由于看起来您已经通过 ParentContainer
和 ChildContainer
管理依赖项组,我认为您不必使用程序集。
使用过 Typhoon 的人可能更喜欢该功能。使用过其他 register
/resolve
类型 DI 容器的人可能更喜欢自己组织容器结构。
2。 func loaded(resolver: ResolverType) 方法的目的是什么?我应该保留解析器吗?会不会导致retain cycle?
在将所有程序集应用于容器后调用它,以便在 Assembly
的 assemble
方法期间执行 运行 不能执行的操作。它被Swinject系统调用,就像UIKit系统调用viewDidLoad
of UIViewController
一样。 The documentation about loaded
or a unit test 可能会帮助您理解 loaded
函数。
您不应存储 resolver
参数。 (其实我没有看到用例来存储它,因为Assembler
不保留对程序集的引用,它会在你实例化后释放Assembler
。即使你存储它,也不会导致保留循环。 )
3.我想要 TopLevelAssembly,但仍将容器用于叶实体。是否可以将 Assembly 作为容器的父级传递?或者还有其他方法可以实现吗?
我没听懂您关于 TopLevelAssembly 和叶实体的上下文。如果您添加更多详细信息,我将能够稍后更新我的答案。
以下是对问题部分的一些评论:您不能传递 Assembly
实例,因为 Container
的初始化程序是 init(parent: Container? = nil)
,它采用 Container
的实例.实现它的另一种方法可能只是将顶层保持为 Container
。 (或者我必须更新 Swinject 以支持该场景。)
我的回答可能并不完美,但我希望它能帮助您实现服务定位器模式。
我在我的项目中使用很棒的 Swinject 作为 DI,但我在没有程序集的情况下使用它(当我开始使用 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,可以使用依赖项)
- 即使手动构建,我也可以停止 using/switch DI 框架并替换
Container
(我的代码不知道任何框架),因为我的代码调用:let topController = ParentContainer().myTopLevelController()
现在我正在尝试申请 Assembly
。据我所知,my 容器现在将符合 AssemblyType
协议。但是我有些困惑:
- 我应该通过程序集而不是通过容器来解析实例吗?
func loaded(resolver: ResolverType)
方法的目的是什么?我应该保留解析器吗?会导致retain cycle吗?- 我想要 TopLevelAssembly,但仍将容器用于叶实体。是否可以将 Assembly 作为容器的父级传递?或者还有其他方法可以实现吗?
1.我应该通过程序集而不是容器来解析实例吗?
是否使用汇编功能由您决定。它被使用 to manage grouping of dependencies。由于看起来您已经通过 ParentContainer
和 ChildContainer
管理依赖项组,我认为您不必使用程序集。
使用过 Typhoon 的人可能更喜欢该功能。使用过其他 register
/resolve
类型 DI 容器的人可能更喜欢自己组织容器结构。
2。 func loaded(resolver: ResolverType) 方法的目的是什么?我应该保留解析器吗?会不会导致retain cycle?
在将所有程序集应用于容器后调用它,以便在 Assembly
的 assemble
方法期间执行 运行 不能执行的操作。它被Swinject系统调用,就像UIKit系统调用viewDidLoad
of UIViewController
一样。 The documentation about loaded
or a unit test 可能会帮助您理解 loaded
函数。
您不应存储 resolver
参数。 (其实我没有看到用例来存储它,因为Assembler
不保留对程序集的引用,它会在你实例化后释放Assembler
。即使你存储它,也不会导致保留循环。 )
3.我想要 TopLevelAssembly,但仍将容器用于叶实体。是否可以将 Assembly 作为容器的父级传递?或者还有其他方法可以实现吗?
我没听懂您关于 TopLevelAssembly 和叶实体的上下文。如果您添加更多详细信息,我将能够稍后更新我的答案。
以下是对问题部分的一些评论:您不能传递 Assembly
实例,因为 Container
的初始化程序是 init(parent: Container? = nil)
,它采用 Container
的实例.实现它的另一种方法可能只是将顶层保持为 Container
。 (或者我必须更新 Swinject 以支持该场景。)
我的回答可能并不完美,但我希望它能帮助您实现服务定位器模式。