Search code examples
iosswiftdependency-injectionlazy-initializationtyphoon

Typhoon lazy injection in Swift


While trying and playing around with Typhoon DI, I realized that LazySingleton scope is not working as expected meaning lazy properties are injected even before they are used. Being more concrete I created a TyphoonAssembly as follow :

public class AppAssembly : TyphoonAssembly {

    public dynamic func knight() -> AnyObject{

        return TyphoonDefinition.withClass(Knight.self){
            (definition) in

            definition.injectProperty("name", with: "Dragon")

            definition.injectProperty("horse")

            definition.scope = TyphoonScope.LazySingleton

        }
    }

    public dynamic func horse() -> AnyObject{

        return TyphoonDefinition.withClass(Horse.self){
            (definition) in

            definition.injectProperty("color", with: "red")

            definition.scope = TyphoonScope.LazySingleton
        }
    }

}

where Knight is NSObject and has validateProperties function

class Knight:NSObject {

    var name:String?
    var horse: Horse?

    func validateProperties(){

        if name != nil{

            println("Name not nil")
        }

        if horse != nil{

            println("Horse not nil")
        }
    }
}

After activating assembly and getting knight from it, calling validateProperties function always print Name not nil and Horse not nil even these properties are never used in my code. Am I missing something here or simply lazy injection does not work same as Swift lazy stored properties do?


Solution

  • Your interpretation of the term lazy singleton makes sense, but its not the correct one. TyphoonScopeLazySingleton means that Typhoon won't instantiate the whole object until its asked for. Once asked for all properties will be injected. There's no proxying to inject on demand - if you're interested in such a feature, would you mind raising an issue for us in Github?

    You're right that such a feature would only work in Swift if the class extended NSObject and the properties were types compatible with Objective-C, as "pure" Swift uses C++ style static dispatch, and therefore runtime method interception/proxying is not possible.

    Here's the user guide for Typhoon scopes.