It is my first project using Swinject and I want to make sure I use it properly.
Coming from a C++/Objective-C background, I don't have much experience with dependency injection containers.
I follow the MVVM architecture, use SwinjectStoryboard
and let the storyboard instantiate all the view controllers for me.
Here is my setup:
extension SwinjectStoryboard {
class func setup() {
// View Controllers
defaultContainer.registerForStoryboard(ItemsCollectionViewController.self) { resolver, controller in
controller.viewModel = resolver.resolve(ItemsCollectionViewModelProtocol.self)
controller.imageLoader = resolver.resolve(ImageLoaderProtocol.self)
}
// View Models
defaultContainer.register(ItemsCollectionViewModelProtocol.self) { resolver in
return ItemsCollectionViewModel(userSession: resolver.resolve(UserSessionProtocol.self)!)
}
// Services
defaultContainer.register(UserSessionProtocol.self) { resolver in
return UserSession(webService: resolver.resolve(WebServiceProtocol.self)!)
}.inObjectScope(.Hierarchy)
defaultContainer.register(WebServiceProtocol.self) { resolver in
return CloudKitService()
}.inObjectScope(.Hierarchy)
defaultContainer.register(ImageLoaderProtocol.self) { resolver in
let imageLoader = ImageLoader(fetcher: resolver.resolve(ImageFetcherProtocol.self)!,
cache: resolver.resolve(ImageCacheProtocol.self)!)
return imageLoader
}
defaultContainer.register(ImageFetcherProtocol.self) { resolver in
return CloudKitImageFetcher(database: .PublicDatabase)
}
defaultContainer.register(ImageCacheProtocol.self) { resolver in
return ImageDiskCache(location: .CachesDirectory, subDirectory: "items/pictures")
}
}
}
A few questions:
Is it OK to use the
defaultContainer
provided by the storyboard for everything?Am I right to assume that there is no way to use initializer injection for the view controllers and therefore no way to make their
viewModel
property private?In this setup, does it make a difference if I use the
.Hierarchy
or.Container
scope?
All feedback welcome.