Container is a lightweight dependency injection framework for Swift.
is available in the Swift Package Manager.
https://github.com/bartleby/Container.git
Firstly, you must defined your containers
extensionContainer{staticletservices=Container(ContainerConfigurator.services)staticletassemblies=Container(ContainerConfigurator.assemblies)staticletappearance=Container(ContainerConfigurator.appearance)}structContainerConfigurator{staticvarservices:DependencyResolver{letcontainer=DependencyContainer()
container.apply(Service()asServiceProtocol)
container.apply(ServiceTwo(), label:.two)return container
}staticvarassemblies:DependencyResolver{letcontainer=DependencyContainer()
container.apply(MainAssembly())
container.apply(AuthorizationAssembly())
container.apply(RegistrationAssembly())
container.apply(OnboardingAssembly())
container.apply(SettingsAssembly())return container
}staticvarappearance:DependencyResolver{letcontainer=DependencyContainer()
container.apply(Color.red, label:.redColor)return container
}}Then get an instance of a service from the container.
letresolver=Container.services.resolver
letservice= resolver.resolve(Service.self, scope:.unowned)
service.run()You can also use Propertywrapers
classViewModel{@Dependency(.services, scope:.strong)varconfig:AppConfigServiceProtocol
//...
func setup(){lettoken= config.obtain(for:.token)
//...
}}You can specify the scope for your dependencies, .weak.strong and .unowned
.weak scope is used by default
@Dependency(.services)varservice:ServiceProtocol // .weak scope is used by defaultHow it's work
weakKeeps the object in memory while at least one object refers to itstrongAn analogue of Singletone, after creating the object, it always remains in memory even if no one refers to itunownedThe object is not stored in memory and each time create a new object
For the same types, you can specify Label For exemple:
container.apply(Color.red, label:.redColor)
container.apply(Color.green, label:.greenColor)
container.apply(Color.orange, label:.orangeColor)In order to create your own Label, you need to extension the structure of DependencyLabel
extensionDependencyLabel{staticletredColor=ContainerLabel(value:"redColor")staticletgreenColor=ContainerLabel(value:"greenColor")staticletorangeColor=ContainerLabel(value:"orangeColor")}Then you can specify a label when using
@Dependency(.appearance, scope:.strong, label:.redColor)varredColor:ColorYou'r also can use Assembly for assembly your Modules with Container
First, register a Assembly to a Container
extensionContainer{staticletassembly=Container(ContainerConfigurator.assemblies)
//...
}structContainerConfigurator{staticvarassemblies:DependencyResolver{letcontainer=DependencyContainer()
container.apply(MainAssembly())
container.apply(AuthorizationAssembly())
container.apply(RegistrationAssembly())
container.apply(OnboardingAssembly())
container.apply(SettingsAssembly())return container
}
//...
}Then implement the MainAssembly class
protocolAssembly{associatedtypeC:CoordinatorTypeassociatedtypeMfunc build(coordinator:C)->M}typealiasMainModule=Module<MainModuleInput,MainModuleOutput>structMainAssembly:Assembly{@Dependency(.services, scope:.strong)varconfig:AppConfigServiceProtocolfunc build(coordinator:MainCoordinator)->MainModule{
// View
letview=MainViewController()
// Router
letrouter=MainRouter(coordinator: coordinator)
// ViewModel
letviewModel=MainViewModel(router: router, config: config)
// Configure
viewModel.view = view
view.output = viewModel
returnModule(view: view, input: viewModel, output: viewModel)}}classMainCoordinator:BaseCoordinator{
// MARK: - Dependencies
@Dependency(.assemblies)varmainAssembly:MainAssemblyoverridefunc start(){letmodule= mainAssembly.build(coordinator:self)
router.setRootModule(module)}}Coming soon
MIT license. See the LICENSE file for details.
