台风初始化注射器&调用super.init()

时间:2015-07-14 11:23:16

标签: ios swift dependency-injection typhoon

我在子类中有一个父类和子类以及一个初始化程序,它接受一些参数,然后调用super.init()来初始化基类的属性。

因为我有很多子类,所以我想重用代码来注入参数但是我不能找到一种方法来注入基类定义中的一些成员,而其余成员则注入子类课程定义。

我尝试了以下内容:

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个参数。有没有办法让这项工作成功,或者我必须将基本参数重构为属性,如文档中的示例?

1 个答案:

答案 0 :(得分:1)

您可以从父级继承初始值设定项或覆盖它,但遗憾的是,除了父模板中定义的参数之外,您无法扩展具有额外参数的初始值设定项。

建议的替代方案:

使用属性注入

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

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

使用合成而非继承

另一个建议是创建一个适当的作用域定义,该定义封装了易于一起使用并注入的配置。

根据具体情况,这可能是有利的 - 有很多关于“组合与继承”的好文章。当每个都合适时。