コンストラクタインジェクション
イニシャライザを通して依存関係を渡します。
「コンストラクタインジェクション」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。
コンストラクタインジェクション
最も一般的なDIの形式は、依存関係をイニシャライザ経由で渡す方法です。オブジェクトは作成時に必要なものをすべて受け取り、保持します。
基本的なinit
保存プロパティを宣言し、initで値を代入します。呼び出し側は、オブジェクトを作成するために依存関係を渡す必要があります。
struct Greeter { func hi() -> String { "Hi" } }
struct View {
let greeter: Greeter
init(greeter: Greeter) { self.greeter = greeter }
func show() { print(greeter.hi()) }
}
View(greeter: Greeter()).show()不変の依存関係
注入するプロパティにletを使うと不変になるため、構築後に依存関係を差し替えられなくなります。
struct Engine { let hp: Int }
struct Car {
let engine: Engine // cannot change later
init(engine: Engine) { self.engine = engine }
}
let c = Car(engine: Engine(hp: 150))
print(c.engine.hp)複数の依存関係
複数の協調オブジェクトを注入するには、複数のパラメータを列挙します。イニシャライザが必要条件の全体を示します。
struct DB { func get() -> Int { 7 } }
struct Cache { func put(_ v: Int) { print("cached \(v)") } }
struct Service {
let db: DB
let cache: Cache
init(db: DB, cache: Cache) { self.db = db; self.cache = cache }
func run() { cache.put(db.get()) }
}
Service(db: DB(), cache: Cache()).run()デフォルト引数値
デフォルト値を設定すると、本番では呼び出し側が依存関係を省略しながら、テストでは上書きできるようになります。
struct Logger { func log(_ m: String) { print(m) } }
struct Service {
let logger: Logger
init(logger: Logger = Logger()) { self.logger = logger }
func run() { logger.log("go") }
}
Service().run() // uses defaultクラスへのコンストラクタインジェクション
クラスでも同じパターンに従います。イニシャライザは、インスタンスを使用可能にする前に各依存関係を代入します。
class Mailer { func send() { print("sent") } }
class Signup {
let mailer: Mailer
init(mailer: Mailer) { self.mailer = mailer }
func go() { mailer.send() }
}
Signup(mailer: Mailer()).go()値の注入
依存関係はオブジェクトである必要はありません。ベースURLやフラグなどの設定値も、同じ方法で注入できます。
struct Client {
let baseURL: String
init(baseURL: String) { self.baseURL = baseURL }
func endpoint(_ p: String) -> String { baseURL + p }
}
print(Client(baseURL: "https://api").endpoint("/users"))コンポジションルート
アプリのエントリポイント近くにある1か所で、オブジェクトグラフ全体を配線します。それ以外のコードは、用意された依存関係を受け取るだけです。
struct DB { func count() -> Int { 3 } }
struct Repo { let db: DB; func n() -> Int { db.count() } }
struct App { let repo: Repo; func run() { print(repo.n()) } }
// Composition root:
let app = App(repo: Repo(db: DB()))
app.run()隠れたグローバルの回避
コンストラクタインジェクションは、隠れたグローバルへのアクセスを置き換えます。各依存関係が明示されるため、データの流れを追跡できます。
struct Settings { let theme: String }
struct Screen {
let settings: Settings
func render() { print("Theme: \(settings.theme)") }
}
Screen(settings: Settings(theme: "dark")).render()必須とオプション
依存関係が本当に任意の場合はオプショナル型で表現します。そうでなければ必須にして、設定が不完全な状態のオブジェクトが存在できないようにします。
struct Analytics { func track() { print("tracked") } }
struct Flow {
let analytics: Analytics?
func step() { analytics?.track() }
}
Flow(analytics: Analytics()).step()
Flow(analytics: nil).step()コンストラクタインジェクションの理由
完全に初期化されたオブジェクトが保証され、依存関係が明確になり、letによる不変性も利用できます。Swiftでは、これをデフォルトの方法として推奨します。
struct Adder { func add(_ a: Int, _ b: Int) -> Int { a + b } }
struct Calc {
let adder: Adder
init(adder: Adder) { self.adder = adder }
}
print(Calc(adder: Adder()).adder.add(4, 5))確認問題
コンストラクタインジェクションがよく推奨されるのはなぜですか。
まとめ
コンストラクタインジェクションでは、依存関係をinit経由で渡し、通常は不変のletプロパティとして保持します。オブジェクトや値を注入でき、デフォルト値を指定でき、コンポジションルートですべてを配線できます。次は、具体的な型ではなくプロトコルを注入します。
よくある質問
「コンストラクタインジェクション」レッスンは無料ですか?
はい。「コンストラクタインジェクション」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。
「コンストラクタインジェクション」で何を学びますか?
イニシャライザを通して依存関係を渡します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Swift Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「コンストラクタインジェクション」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSwift Academyレッスンでコードを書いて実行できますか?
はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 依存性注入を使う理由
- コンストラクタインジェクション
- プロトコルベースの抽象化
- テストでの依存関係のモック化