ios - Why is Swinject model class registered without ".inObjectScope( .Container )" producing a singleton? -
this question people lot of experience of swinject swift.
i show problematic code, , question @ bottom.
there's quite lot of code, sorry that.
this myswinjectstoryboard.swift
registration:
import swinject extension swinjectstoryboard { class func setup () { defaultcontainer.register( stopwatch.self ) { responder in stopwatch( signals: responder.resolve( signalsservice.self )! ) } defaultcontainer.register( signalsservice.self ) { _ in signalsservice() }.inobjectscope( .container ) defaultcontainer.register( imageservice.self ) { responder in imageservice( signals: responder.resolve( signalsservice.self )! , stopwatch: responder.resolve( stopwatch.self )! ) }.inobjectscope( .container ) defaultcontainer.registerforstoryboard( startupviewcontroller.self ) { resolvable, viewcontroller in viewcontroller.stopwatch = resolvable.resolve( stopwatch.self )! viewcontroller.image = resolvable.resolve( imageservice.self )! } } }
this stopwatch.swift
, pauses while before firing oncomplete handler:
import foundation class stopwatch: stopwatchprotocol { var key: string { return "stopwatch_\( _key ).complete" } private var _signals: signalsprotocol , _key: uint16 , _timer: nstimer? , _data: anyobject? func startwith ( delay delay: double , forlistener closure: ( string, any? ) -> void ){ _data = nil _startwith( delay: delay, forlistener: closure ) } func stop () { guard let timer = _timer else { return } timer.invalidate() _timer = nil _data = nil } private func _startwith ( delay delay: double , forlistener closure: ( string, any? ) -> void ){ stop() _timer = nstimer.scheduledtimerwithtimeinterval( nstimeinterval( delay ) , target: self , selector: #selector( _ontimercomplete ) , userinfo: nil , repeats: false ) } @objc private func _ontimercomplete () { stop() print( "stopwatch key `\( key )` complete." ) } required init ( signals: signalsprotocol ) { _signals = signals _key = getprimarykey() print( "primary key: \( _key )" ) } }
imageservice.swift
presently accepts signals , stopwatch property via init
function:
protocol imageprotocol {} class imageservice: imageprotocol { private let _signals: signalsprotocol , _stopwatch: stopwatchprotocol required init ( signals: signalsprotocol , stopwatch: stopwatchprotocol ){ _signals = signals _stopwatch = stopwatch lo( "imageservice key: \( _stopwatch.key )" ) } }
signalsservice.swift
empty model class:
protocol signalsprotocol {} class signalsservice: signalsprotocol {}
whilst startupviewcontroller.swift
basic uiviewcontroller
accepts injected properties:
import uikit class startupviewcontroller: uiviewcontroller { var image: imageservice? { willset { guard _image == nil else { return } _image = newvalue } } var signals: signalsservice? { willset { guard _signals == nil else { return } _signals = newvalue } } var stopwatch: stopwatchprotocol? { willset { guard _stopwatch == nil else { return } _stopwatch = newvalue print( "startupviewcontroller key: \( _stopwatch.key )" ) } } internal var _image: imageservice! , _signals: signalsservice! , _stopwatch: stopwatch! }
and getprivatekey()
global static, returning unique ints:
private var _primarykey = uint16( 0 ) func getprimarykey () -> uint16 { _primarykey += 1 return _primarykey }
now understand it, way have registered stopwatch.swift
in myswinjectstoryboard.swift
means each time instance injected, new, discrete instance. however, both imageservice.swift
, startupviewcontroller.swift
being injected same instance:
startupviewcontroller key: stopwatch_2.complete imageservice key: stopwatch_2.complete
imageservice
's key ought be:
imageservice key: stopwatch_3.complete
does know why happening, please? thank you.
default scope services .graph
. documentation:
with objectscope.graph, instance created, in objectscope.none, if directly call resolve method of container, instances resolved in factory closures shared during resolution of root instance construct object graph.
if want unique instance created each reference during object graph resolution, should use object scope .none
, i.e.
defaultcontainer.register(stopwatch.self) { resolver in stopwatch(signals: resolver.resolve(signalsservice.self)!) }.inobjectscope(.none)
Comments
Post a Comment