2

I am using Swinject for Dependency Injection. I have created a DependencyManager which has a shared instance of container.

internal class DependencyManager {
private static let sharedInstance = DependencyManager()

private var assembler: Assembler
private let container: Container

class func getResolver() -> Resolver {
    return self.sharedInstance.assembler.resolver
}

class func getContainer() -> Container {
    return self.sharedInstance.container
}

private init() {
    self.container = Container()
    let assembler = Assembler([
        LoginFactory()
        ])
    self.assembler = assembler
}

}

LoginFactory class implements Assembly

internal class LoginFactory: Assembly {
func assemble(container: Container) {
    container.register(LSViewModel.self) { res in
        return LSViewModel()
    }
    container.register(LSCoordinator.self, factory: { res in
        let lsc = LSCoordinator(window: AppDelegate.mainWindow!)
        lsc.viewModel = res.resolve(LSViewModel.self)
        return lsc
    })
}

}

I read Assembly documentation where it says that it is better used for organization - https://github.com/Swinject/Swinject/blob/master/Documentation/Assembler.md. If I had not been using Assembly then I would have used commands like

        DependencyManager.getContainer().register(LSViewModel.self) { _ in LSViewModel() }
    DependencyManager.getContainer().register(LSCoordinator.self, factory: { (res) in
        let lsc = LSCoordinator(window: AppDelegate.mainWindow!)
        lsc.viewModel = res.resolve(LSViewModel.self)
        return lsc
    })
    let lsCoordinator: LSCoordinator = DependencyManager.getContainer().resolve(LSCoordinator.self)!

Both the implementations are working as expected, without any crashes. I wonder why Assembly is even an advantage? I am doing the same thing without using Assembly without an overhead.

Ped7g
  • 16,236
  • 3
  • 26
  • 63
A_G
  • 2,260
  • 3
  • 23
  • 56

1 Answers1

3

Benefits of organising your code using Assembly will start to out-weight the "no overhead" system once the project gets big enough. One way of keeping your code modularised and reusable is (amongst other stuff):

  1. Keep DI code for different features separately
  2. Features do not have the knowledge of how the final app is put together (e.g. DependencyManager)

IMO 1. is quite intuitive. 2. less so, but is free when using assemblies and gives you a lot of flexibility - for example you might want to reuse the feature in multiple apps (e.g. Networking).

Using assemblies you would have something like

let assembler = Assembler([
    LoginAssembly(), // each assembly contains DI code for one feature
    HomepageAssembly(),
    UserProfileAssembly(),
    // ...
])

while using the intuitive approach might get quite messy.

Jakub Vano
  • 3,833
  • 15
  • 29