Swinject:如何将委托模式与接口隔离(类与接口)一起使用?
Posted
技术标签:
【中文标题】Swinject:如何将委托模式与接口隔离(类与接口)一起使用?【英文标题】:Swinject: How to use delegate pattern with interface segregation (class vs interface)? 【发布时间】:2019-09-11 18:02:18 【问题描述】:我正在努力解决注入依赖问题。现在问题来了,在委托模式的情况下如何使用接口隔离原则?我正在使用 Swinject 框架进行依赖注入。我该如何解决这个问题?
class Client
private var interface: ParentInterface
...
func execute()
interface = globalContainer.resolve(ParentInterface.self)
interface?.parentMethod()
protocol ParentInterface
func parentMethod()
class Parent: ParentInterface, ParentDelegate
// Dependency
private var child: Child? // ???? I WANT TO USE AN PROTOCOL HERE, NOT THE CLASS
init(childReference: Child)
self.child = childReference
self.child?.delegate = self // ???? But if I use the protocol I cant access the delegate property
public func parentMethod()
let result = calcSomething()
// Access child class interface method
child?.childMethod(result)
...
子类,目前没有什么异常。
protocol ParentDelegate: class
func delagteMethod(value: Double)
protocol ChildInterface
func childMethod(_ result: Double)
class Child: ChildInterface
weak var delegate: ParentDelegate?
...
private func delagteMethod()
delegate?.delagteMethod(value: someValue)
但是要正确注入依赖项,我需要一个协议而不是直接的类引用,对吧?像这样:
// ???? Would like to
container.register(ParentInterface.self) r in
Parent(childInterface: r.resolve(ChildInterface.self)!)
// ???? Only way I get it working without interface
container.register(ParentDelegate.self) r in
Parent(childClass: Child())
container.register(ChildInterface.self) _ in Child()
.initCompleted r, c in
let child = c as! Child
child.delegate = r.resolve(ParentDelegate.self)
简而言之,我在绕圈子。如果我为子类使用接口,我无法访问委托属性,如果我使用类引用,我无法合理模拟/存根接口方法。
我错过了什么?提前非常感谢!
【问题讨论】:
【参考方案1】:我建议从Parent
构造函数中删除self.child?.delegate = self
,原因有两个:
-
不应该由 DI 框架负责连接所有依赖项吗?
特别是在 Swinject 中,这可能会导致不正确的依赖关系,请参阅 the remark in docs
我倾向于使用的模式或多或少是您想出的:
class Parent: ParentInterface, ParentDelegate
init(child: ChilInterface) self.child = child
class Child: ChildInterface
weak var parent: ParentDelegate?
container.register(ParentInterface.self) Parent(child: $0.resolve(ChildInterface.self)!)
.implements(ParentDelegate.self)
container.register(ChildInterface.self) _ in Child()
.initCompleted ($1 as! Child).delegate = $0.resolve(ParentDelegate.self)
此外,如果您想摆脱强制转换,您可以执行以下操作:
container.register(Child.self) _ in Child()
.implements(ChildInterface.self)
.initCompleted $1.delegate = $0.resolve(ParentDelegate.self)
【讨论】:
以上是关于Swinject:如何将委托模式与接口隔离(类与接口)一起使用?的主要内容,如果未能解决你的问题,请参考以下文章