台风初始化程序注入和调用 super.init()

Typhoon initializer injection & calling super.init()

我有一个 parent 和 child class 以及 child class 中的一个初始值设定项,它接受一些参数然后调用 super.init() 从基础 class.

初始化属性

因为我有很多 child classes 我想重用代码来注入参数,但我想不出一种方法来注入基础 class 定义和 child class 定义中的其余部分。

我尝试了以下方法:

public dynamic func baseManager() -> AnyObject {
    return TyphoonDefinition.withClass(BaseManager.self) {
        (definition) in

        definition.useInitializer("initWithBaseParam1:baseParam2:") {
            (initializer) in

            initializer.injectParameterWith(self.baseParam1())
            initializer.injectParameterWith(self.baseParam2())
        }
    }
}

public dynamic func authenticationManager() -> AnyObject {

    return TyphoonDefinition.withClass(AuthenticationManager.self) {
        (definition) in

        definition.parent = self.baseManager()
        definition.useInitializer("initWithChildParam1:childParam2:baseParam1:baseParam2:") {
            (initializer) in

            initializer.injectParameterWith(self.childParam1())
            initializer.injectParameterWith(self.childParam2())
        }
    }
}

但是我得到一个错误,我使用了一个带有 4 个参数的初始化器,但只注入了其中的 2 个。有什么方法可以完成这项工作,还是我必须将基本参数重构为类似于文档中示例的属性?

您可以从父模板继承初始化器或重写它,但不幸的是,除了父模板中定义的参数之外,您不能使用额外参数扩展初始化器。

建议的备选方案:

使用属性注入

通常我们建议支持初始化器注入,它允许创建不可变对象并在构造后进行状态验证。 属性 注入中的这些缺点可以通过以下方式解决:

  • 指定 a callback method 在注入属性后使用。
  • 对于设计为不可变的实例,将属性声明为内部可读写,但外部只读。

使用组合而不是继承

另一个建议是创建一个适当范围的定义,封装倾向于一起使用的配置并注入它。

根据情况,这可能是有利的 - 'composition vs inheritance' 上有很多好文章,每篇文章都适合。