I guess this may be just for keeping the example simple enough. But there are a couple of bad practices here that violates a couple of principles. just for the record of someone reading comments and wanting to go into more details, I'll list out a few things to improve. * Making a dependency optional just because the framework works that way is not good, not only makes you type defensive code (like setting a default value if the dependency is not injected correclty) but also expreses an incorrect fact about the class. receiving an optional value means that the class will be able to work without that value. * Referencing and configuring the container from something other than the root composition layer is a bad/incomplete implementation of the solid principles - S: Your ViewController class is not only responsible for the UI, but for creating the next instance of the SecondVC. - O: You can't change to what VC you'll be navigating without modifying the ViewControllers' class code. - L and ID: Since ViewController is depending on the container, configuring it and instantiating the next VC, (described above) this makes imposible to swap this functionality with a different implementation or even aggregate or compose more functionality. View Controller should have received on it's constructor an abstraction of what's needed to be done, or what happened, and the implementation of that should have been injected (an abstraction can be a Protocol, but a function as well!) simplified example: ``` ViewController { init(onButtonTapped: (() -> Void)?) func didTapButton() { onButtonTapped?() } } ``` Then whoever creates the ViewController is in charge of configuring the Container and creating the Second VC as well the responsable for that, is the root composition layer This layer lives as close to the app's start point as possible, because is app specific. simplified example: ``` SceneDelegate { func loadSceneForWindow() { let container = Container() // configure container and register dependencies ViewController(onButtonTapped: { container.resolve(SecondVC)... } ) } } ``` This may be a bit more advanced, but it's the complete story on how and why implementing the SOLID principles lead to more composable and maintainable code. as you may see, if you move everything that's composition related to the composition root, the need for a Container is rather debatable, since the code for managing instances is extremely simple
I believe there will be a potential / need to use this way. But as a mid-senior dev, I didnt fully understand the use case of this complex implementation
one such use case is testing, by passing object in constructor, you can change implementation of protocol to either actual object or mock object, lets say on SecondVC constructor you need network repository that call method getCityArray , in actual implementation you pass the actual object of network repository that handle API call to call getCityArray, but this implementation would be costly if you use CI/CD on every test, alternatively you can use a mock network repository that return immediately a fake array of city
I have recently gotten involved with DI on the project I'm working on. My senior told me to do a research about this exact framework and I did. But I was expecting it to be more Swifty. After a month of loose working on the subject I have developed my own DI framework which was working via the property wrappers for syntactic sugary (e.g. injecting the dependencies with @Injected keyword as properties and some more features). I don't know if there is some deep architectural programming with Swinject but from your lovely video I must say that it is what I thought it is. Except maybe the part where you pointed out that the dependencies aren't initiated before calling. But for my use case I needed to replace some singletons which ought to work globally and hold data globally and be same everywhere and make them testable. If there is more to Swinject that I didn't catch yet or some advanced features of it, if you have the time I would love to see your take on it. Please keep up the good work mate and thank you for sharing your wisdom with us. Cheers!
It looks like Swinject works in runtime, meaning we can't catch dependencies bugs during compilation. Are there other alternatives that work during compile time?
Intended as constructive feedback: Your tutorials are great, but please could you review how often you say "go ahead" in your voiceover. This applies to all the vids, but as an example, it's said 82 times in this video (I counted), and a lowlight is at 8:46, where "we're gonna go ahead and say go ahead..." 😬
@@iOSAcademy I saw Resolver the other day, it looks like a great library, would you suggest any others? I need to present some alternatives to other devs so we can pick one to use on a new app.
Hello Afraz, I am checking in with you again about the view model problem I have been having for months from one of your lessons. You asked me to reach out to you. I have continued leaving comments on your videos so I can get a meeting with you. Please please please, can you reach out.
Nice video for beginners. One question tho: why don’t you use swift package manager in such videos? New iOS developers will likely not use cocoapods on real projects.
@@iOSAcademy those projects might also use objective-c in many places but it does not mean other projects also need to use old technologies like objective-c or cocoapods
Sorry but all I'm seeing is tons of complexity just to show a VC with a random color. I'd rather see videos that convince me on why I would even bother with this, so more of an actual real life example.
Thanks for the feedback. This video is a primer with an expectation the viewer is familiar with DI. Ill be doing more videos with more complex real world examples. Stay tuned
@@iOSAcademy I know, and you know why - Legacy! But you have no legacy, you’re free, and you can help this legacy to be gone :) and thanks for your response!
@@RostyslavKobizsky Just because it’s legacy doesn’t mean it should be avoided. If you’re going for an iOS job most of them today are looking for UIKit with maybe some SwiftUI. So it doesn’t hurt to work with it or at least see it.
I guess this may be just for keeping the example simple enough. But there are a couple of bad practices here that violates a couple of principles.
just for the record of someone reading comments and wanting to go into more details, I'll list out a few things to improve.
* Making a dependency optional just because the framework works that way is not good, not only makes you type defensive code (like setting a default value if the dependency is not injected correclty) but also expreses an incorrect fact about the class. receiving an optional value means that the class will be able to work without that value.
* Referencing and configuring the container from something other than the root composition layer is a bad/incomplete implementation of the solid principles
- S: Your ViewController class is not only responsible for the UI, but for creating the next instance of the SecondVC.
- O: You can't change to what VC you'll be navigating without modifying the ViewControllers' class code.
- L and ID: Since ViewController is depending on the container, configuring it and instantiating the next VC, (described above) this makes imposible to swap this functionality with a different implementation or even aggregate or compose more functionality.
View Controller should have received on it's constructor an abstraction of what's needed to be done, or what happened, and the implementation of that should have been injected (an abstraction can be a Protocol, but a function as well!)
simplified example:
```
ViewController {
init(onButtonTapped: (() -> Void)?)
func didTapButton() {
onButtonTapped?()
}
}
```
Then whoever creates the ViewController is in charge of configuring the Container and creating the Second VC as well
the responsable for that, is the root composition layer
This layer lives as close to the app's start point as possible, because is app specific.
simplified example:
```
SceneDelegate {
func loadSceneForWindow() {
let container = Container()
// configure container and register dependencies
ViewController(onButtonTapped: { container.resolve(SecondVC)... } )
}
}
```
This may be a bit more advanced, but it's the complete story on how and why implementing the SOLID principles lead to more composable and maintainable code.
as you may see, if you move everything that's composition related to the composition root, the need for a Container is rather debatable, since the code for managing instances is extremely simple
I believe there will be a potential / need to use this way. But as a mid-senior dev, I didnt fully understand the use case of this complex implementation
one such use case is testing, by passing object in constructor, you can change implementation of protocol to either actual object or mock object, lets say on SecondVC constructor you need network repository that call method getCityArray , in actual implementation you pass the actual object of network repository that handle API call to call getCityArray, but this implementation would be costly if you use CI/CD on every test, alternatively you can use a mock network repository that return immediately a fake array of city
WOW! That's what I needed so much after entering a project with swinject. Also would be nice to see a video about Kingfisher
You got it!
I have recently gotten involved with DI on the project I'm working on. My senior told me to do a research about this exact framework and I did. But I was expecting it to be more Swifty. After a month of loose working on the subject I have developed my own DI framework which was working via the property wrappers for syntactic sugary (e.g. injecting the dependencies with @Injected keyword as properties and some more features). I don't know if there is some deep architectural programming with Swinject but from your lovely video I must say that it is what I thought it is. Except maybe the part where you pointed out that the dependencies aren't initiated before calling. But for my use case I needed to replace some singletons which ought to work globally and hold data globally and be same everywhere and make them testable.
If there is more to Swinject that I didn't catch yet or some advanced features of it, if you have the time I would love to see your take on it. Please keep up the good work mate and thank you for sharing your wisdom with us. Cheers!
I was waiting this kind of topic. For example Solid Principle and dependency injection. Thank you for making this video.
Youre welcome
You the best! Thanks for the great tutorial.
Thanks
It looks like Swinject works in runtime, meaning we can't catch dependencies bugs during compilation. Are there other alternatives that work during compile time?
How did you direct add that button code can you explain it?
Intended as constructive feedback: Your tutorials are great, but please could you review how often you say "go ahead" in your voiceover. This applies to all the vids, but as an example, it's said 82 times in this video (I counted), and a lowlight is at 8:46, where "we're gonna go ahead and say go ahead..." 😬
Lol I GIVE YOU PROPS FOR COUNTING. Good feedback for me though
@@iOSAcademy Well meant feedback, thanks for taking it as intended 😊
once you notice it , you cannot unnotice it 😂
Great video for beginners! 👏🏻👏🏻
Thanks
I think this is great but maybe isolating files would be great too , ty
Thanks for the feedback
Thank you, but I didn't understand the purpose of using it... it seems overengineering to me 🤔
Agreed. I just dont see what problem this would solve. You still create SecondVC directly, its just moved in the other method.
Thanks so much, this is great
Youre welcome
Swift always give dependency injection free like Kotlin/Java Dagger?
Not exactly. You need a framework or to do it manually with interfaces
Top video! thanks.
Thanks
Thank you, exactly what I needed right now 😊 (also seconded on video on Kingfisher)
Coming soon!
Hi - Can you do a video on DIP framework too?
Sure
Great tutorial as always!
Thank you! Cheers!
Yeaahhh finally thanks
Do cleanse also please 🙏
Thanks
I needed it.
glad it helped!
Are there any alternatives to Swinject?
Several
@@iOSAcademy I saw Resolver the other day, it looks like a great library, would you suggest any others? I need to present some alternatives to other devs so we can pick one to use on a new app.
Cool!
Thanks
YEAH BOY ~~~~~
haha thanks!
Hello Afraz, I am checking in with you again about the view model problem I have been having for months from one of your lessons. You asked me to reach out to you. I have continued leaving comments on your videos so I can get a meeting with you. Please please please, can you reach out.
Nice video for beginners. One question tho: why don’t you use swift package manager in such videos?
New iOS developers will likely not use cocoapods on real projects.
Cocoapods are by far way more popular in large professional projects. Like fb, google, etc.
@@iOSAcademy those projects might also use objective-c in many places but it does not mean other projects also need to use old technologies like objective-c or cocoapods
Sorry but all I'm seeing is tons of complexity just to show a VC with a random color. I'd rather see videos that convince me on why I would even bother with this, so more of an actual real life example.
Thanks for the feedback. This video is a primer with an expectation the viewer is familiar with DI. Ill be doing more videos with more complex real world examples. Stay tuned
can't access source code after paid subscription
Whats your github
2022 cocapods - not worth to watch to the end
And UIKit omg dinosaur please stop!
Thanks for the feedback. Just so you are aware Google, Facebook, Netfli, Microsoft, all the other big companies are still using uikit and cocoapods
@@iOSAcademy I know, and you know why - Legacy! But you have no legacy, you’re free, and you can help this legacy to be gone :) and thanks for your response!
@@RostyslavKobizsky Just because it’s legacy doesn’t mean it should be avoided. If you’re going for an iOS job most of them today are looking for UIKit with maybe some SwiftUI. So it doesn’t hurt to work with it or at least see it.