Skip to content

Latest commit

 

History

History
127 lines (94 loc) · 2.95 KB

InjectionPatterns.md

File metadata and controls

127 lines (94 loc) · 2.95 KB

Injection Patterns

Initializer Injection

Initializer injection is a pattern for passing dependencies to a dependent instance by its initializers. Initializer injection is appropriate if the dependent instance cannot work without the dependencies.

The following code defines initializer injection to PetOwner, which depends on Animal:

let container = Container()
container.register(Animal.self) { _ in Cat() }
container.register(Person.self) { r in
    PetOwner(pet: r.resolve(Animal.self)!)
}

Where the protocols and classes are

protocol Animal {
    func sound() -> String
}

class Cat: Animal {
    init() { }

    func sound() -> String {
        return "Meow"
    }
}

protocol Person { }

class PetOwner: Person {
    let pet: Animal

    init(pet: Animal) {
        self.pet = pet
    }
}

Note that the actual type of Animal passed to the initializer of PetOwner is automatically resolved by Swinject when the PetOwner instance is created:

Property Injection

Property injection is a pattern to pass a dependency to a dependent instance via a setter property. Property injection is appropriate if the dependency is optional to the dependent instance.

The following code defines property injection to PetOwner2:

let container = Container()
container.register(Animal.self) { _ in Cat() }
container.register(Person.self) { r in
    let owner = PetOwner2()
    owner.pet = r.resolve(Animal.self)
    return owner
}

Where

class PetOwner2: Person {
    var pet: Animal?

    init() { }
}

Or, you can use initCompleted callback instead of defining the injection in the registration closure:

let container = Container()
container.register(Animal.self) { _ in Cat() }
container.register(Person.self) { _ in PetOwner2() }
    .initCompleted { r, p in
        let owner = p as! PetOwner2
        owner.pet = r.resolve(Animal.self)
    }

Method Injection

Method injection is a similar pattern to property injection, but it uses a method to pass dependencies to a dependent instance.

The following code defines Method Injection to PetOwner3:

let container = Container()
container.register(Animal.self) { _ in Cat() }
container.register(Person.self) { r in
    let owner = PetOwner3()
    owner.setPet(r.resolve(Animal.self)!)
    return owner
}

Where

class PetOwner3: Person {
    var pet: Animal?

    init() { }

    func setPet(pet: Animal) {
        self.pet = pet
    }
}

Or, you can use initCompleted callback instead of defining the injection in the registration closure:

let container = Container()
container.register(Animal.self) { _ in Cat() }
container.register(Person.self) { _ in PetOwner3() }
    .initCompleted { r, p in
        let owner = p as! PetOwner3
        owner.setPet(r.resolve(Animal.self)!)
    }

Next page: Circular Dependencies

Table of Contents