とりあえず書いたら動いたけど、なんだかよくわかっていないのでコードだけ貼っておきます。元ネタはここ。元ネタでは AppContext で頑張って配線しているけど、めんどうくさいのでどうにかならんのか、と思っていろいろいじってたらこうなった。
いろいろ分かったらまとめて記事を書きます。Xcode の Playground で動いたので、貼っていじってみるとよいのではないですかね。
// A & AComponent public protocol A { func getA() -> String } private class AImpl: A { private func getA() -> String { return "a" } } public protocol AComponent { static var a: A { get } } public protocol DefaultAComponent: AComponent {} extension DefaultAComponent { public static var a: A { return AImpl() } } // AB & ABComponent public protocol AB { func getAB() -> String } private class ABUsingA: AB { private let a: A private init(a: A) { self.a = a } private func getAB() -> String { return a.getA() + "b" } } private class SimpleAB: AB { private func getAB() -> String { return "AB" } } public protocol ABComponent { static var ab: AB { get } } public protocol DefaultABComponent: ABComponent {} extension DefaultABComponent where Self: AComponent { public static var ab: AB { return ABUsingA(a: a) } } public protocol SimpleABComponent: ABComponent { static var ab: AB { get } } extension SimpleABComponent { public static var ab: AB { return SimpleAB() } } // Components public typealias Components = protocol<AComponent, ABComponent> public enum DefaultComponents: DefaultAComponent, DefaultABComponent {} let defaultComponents: Components.Type = DefaultComponents.self defaultComponents.a.getA() //=> "a" defaultComponents.ab.getAB() //=> "ab" public enum SimpleComponents: DefaultAComponent, SimpleABComponent {} let simpleComponents: Components.Type = SimpleComponents.self simpleComponents.a.getA() //=> "a" simpleComponents.ab.getAB() //=> "AB"
ウェブ界隈でエンジニアとして労働活動に励んでいる @gomi_ningen 個人のブログです