1

What is the right (cleanest and most concise) way to have PetOwner that can at any later point in program create new instances of Cat?

Let's assume that createAnotherAnimal can be called by PetOwner itself after it gets response to some async request, therefore creating as many instances of Cat as needed at the time of creating PetOwner is not possible.

I solved the problem with injecting factory, but I am not convinced that it is the best way to tackle the problem, what are the alternatives in Swinject?

protocol AnimalType {
    var name: String? { get set }
    func sound() -> String
}

class Cat: AnimalType {
    var name: String?

    init(name: String?) {
        self.name = name
    }

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

protocol PersonType {
    func play() -> String
    func createAnotherAnimal() -> Void
}

class PetOwner: PersonType {
    var pets: [AnimalType] = []
    let petFactory : AnimalFactory

    init(petFactory : AnimalFactory) {
        self.petFactory = petFactory
    }

    func createAnotherAnimal() {

        let pet = petFactory.factoryMethod()
        self.pets.append(pet)
    }

    func play() -> String {
        if(pets.count>0) {
            let pet : AnimalType = pets[0];
            let name = pet.name ?? "someone"
            return "I'm playing with \(name). \(pet.sound())"
        } else {
            return "No animals"
        }
    }
}

class AnimalFactory {
    let factoryMethod : () -> AnimalType

    init(factoryMethod: () -> AnimalType) {
        self.factoryMethod = factoryMethod
    }
}

// Create a container and register service and component pairs.
let container = Container()
container.register(AnimalType.self) { _ in Cat(name: "Mimi") }
container.register(PersonType.self) { r in PetOwner(petFactory: r.resolve(AnimalFactory.self)!) }

container.register(AnimalFactory.self){r in AnimalFactory(factoryMethod:{ () -> AnimalType in r.resolve(AnimalType.self)!}) }

// The person is resolved to a PetOwner with a Cat.
let person = container.resolve(PersonType.self)!

person.createAnotherAnimal()

print(person.play())
deprivat
  • 11
  • 2

0 Answers0