Design Patterns: Dependency Inversion Principle Explained Practically in C# (The D in SOLID)

Share
Embed
  • Published on Apr 23, 2018
  • Newsletter signup (with exclusive discounts): iamtimcorey.com/general-sign-up (your email will be kept safe and you will not be spammed).
    Source Code: iamtimcorey.com/design-patterns-dip/
    When you are writing code, are you doing it right? That is a question that worries a lot of people, and it should probably at least be something every developer thinks through. Design patterns are best practice concepts that we can implement into our code to make it better in some way. Think of them as guardrails that keep our code safe. In this video, we are going to look at the fourth entry in the famous SOLID principle. The I stands for Interface Segregation Principle. We are going to dive into what it means, how it should change our programming practices, and how far we should take it.

Comments • 241

  • KousiK Chatterjee
    KousiK Chatterjee 4 days ago

    how to prevent upper level or lower level to create instances of the concrete classes accidentally except from the factory class? I mean creating Person class instance from the main program?

    • IAmTimCorey
      IAmTimCorey  Day ago

      You prevent it by not doing it. You can’t force the use of the factory.

  • Kevin A
    Kevin A 9 days ago

    Just found your channel. Ive been going through the SOLID saga, and I've learned a ton just from these videos. Thanks for putting all this great content out! Do you have any series that uses this design pattern with the newer Asp.Net Core framework?

  • Nick Fotopoulos
    Nick Fotopoulos 16 days ago

    I learned more from this short video than I did in weeks of browsing and reading on the topic.

  • ionicafardefrica
    ionicafardefrica 16 days ago

    explanation is great, but i still think some of the SOLID and Factory principles are pure bs. It makes the code harder to extend because nobody can read the actual damn code (instead of making it easier, which was the original intent)

    • IAmTimCorey
      IAmTimCorey  16 days ago

      Some of it depends on the size of the project and the team. The key isn't to apply SOLID fully every time. The key is to understand the benefits of SOLID and to apply each principle as needed in any given situation. Over time, you may find that you apply more than you thought you would.

  • Samuel Cramphorn
    Samuel Cramphorn 21 day ago

    Thanks Tim,
    looked online for a lot of examples, glad you actually went through the code and explained it clearly!

  • Richard Kollar
    Richard Kollar 23 days ago

    One of the most useful C# channel out there. Thank you for your will to share the knowledge with us Tim!

  • Daniel Breen
    Daniel Breen Month ago

    Came here to learn about the DIP; Got the added bonus of learning about factories.

  • Toine Koene
    Toine Koene Month ago

    wow, finally i got it, thanks to this video, not the first time i have this with Tim Corey's videos tho.

  • Abdul Rehman
    Abdul Rehman Month ago

    Thank You... I fully understand it... Really Help me a lot.... I have gone through so many examples on youtube.. but this one I found better.

  • Dustin Beach
    Dustin Beach Month ago

    If you wanted a List would you create a method in the Factory class to return a list of IPerson? Anywhere you use 'new' should it be in the Factory class?

    • IAmTimCorey
      IAmTimCorey  Month ago +1

      Not necessarily. Models are typically an exception. That isn't a problem, though, because we aren't actually storing logic in our models so we don't need to replace them with a different type (usually - there are scenarios where it makes sense).

  • Ninh Luyen
    Ninh Luyen 2 months ago

    12:09 "that you will centralize .." So sorry I don't know about why we have create a Factory class centralize for init dependency( new Person(), new Chore()) ?

    • IAmTimCorey
      IAmTimCorey  Month ago

      This is my favorite answer: stackoverflow.com/a/4596353/733798

    • Ninh Luyen
      Ninh Luyen 2 months ago

      Thanks for reply ! but a I have another question, I can't distinction about IOC( inversion of control) and DI(dependency inversion) ?

    • IAmTimCorey
      IAmTimCorey  2 months ago +2

      The centralized factory provides a couple of benefits. First, it fits better with SRP. It has one job - initialize dependencies. Now, people know exactly where to go to look at how dependencies are wired up. They also know where to go to make changes to which classes are handed out when requested. Second, now your code is more testable. You haven't locked in your code to use certain classes. For example, if you new up a Chore class in Main, what is to stop you from newing up a person class inside Chore. Now you are back to tightly-bound applications that are hard to test. Testing effectively really requires a lack of hard dependencies. That means pulling them all back as far as possible. That is what the factory provides.

  • Mark Yosef Dancel
    Mark Yosef Dancel 2 months ago

    "At some point, you have to new up an instance " this cleared my confusion

  • IC
    IC 3 months ago

    What if I want to log in console and into file different logs from Chore class? and I want these loggers to log message with GetType().Name in the front of it. How do you handle this?

    • IC
      IC 3 months ago

      ​@IAmTimCorey Imagine FileLogger and ConsoleLogger, both implement ILogger, but I want to have both of them in single class. How do I do this keeping my code loosely coupled?

    • IAmTimCorey
      IAmTimCorey  3 months ago

      I'm not sure I'm following. If you mean you want different loggers, you can do this with some work. You could also just set up your logger to log different things based upon what is passed in.

  • Mansour Abdelgawad
    Mansour Abdelgawad 3 months ago

    Really valuable Video. Well done Tim Corey!

  • Amon Fesef
    Amon Fesef 3 months ago

    Hi, Tim! Thanks for the brilliant series. =)

    What if we have a lot of places where the IMessageSender is used, but we need to use the Texter class instead the Emailer class only in half of them?
    Should we create an another factory (or a method in the existing), and use it where it's necessary?

    • Amon Fesef
      Amon Fesef 3 months ago

      @IAmTimCorey , thank you!

    • IAmTimCorey
      IAmTimCorey  3 months ago

      You have a few options. One would be to return both and let the caller decide which one they want. Another is to have separate interfaces for the types (each just inheriting from IMessageSender with no additional "stuff" unless needed) and then add both to the factory. It all depends on how you want to set it up.

  • Антон Власюк

    I spent +/- 4 hours (with breaks and by making a lot of notes) to finish your video. You know what? It is definitely worth your time.

    Thank you for sharing this knowledge with people!

    • IAmTimCorey
      IAmTimCorey  3 months ago

      I am glad you got a lot of value out of this video. Good job going beyond listening to actually studying what you watched.

  • Vinay Palaksha
    Vinay Palaksha 4 months ago

    Tim,
    How do you decide between high level modules and low level modules. here you say Statoc void main() depends on Person and Chore class and also Chore class depends on Emailer and Logger. Is there any way we can decide whats level of modules so that it gives much clarity while designing big applications.

    • IAmTimCorey
      IAmTimCorey  4 months ago

      If everything depends on abstractions then you don't really need to worry about it. The high-level modules identify themselves. They are the ones that hook up the concrete classes to the abstractions. It usually comes down to the UI to do that work.

  • Mayron Giron Rodriguez
    Mayron Giron Rodriguez 4 months ago

    Thank you!! very clear!

  • Francis Yankey
    Francis Yankey 4 months ago

    Hi Tim, how would you assign an instance of person with dependency injection? Will you map a Person object to an IPerson interface when registering your components or services?

    • Francis Yankey
      Francis Yankey 4 months ago

      @IAmTimCorey I see

    • IAmTimCorey
      IAmTimCorey  4 months ago

      If you are talking about a data model, usually you don't run those through DI. Instead either you or your data access system (like Dapper or EF) instantiates them for you. There isn't really a benefit to putting pure models through DI. You don't need to replace them for testing. The key is not to mix logic into your model and then muddy the waters.

  • Lex Sh
    Lex Sh 4 months ago

    Hello Tim, sorry for my English, but what if the Logger class needed a private field of the Chore class to work and it needed it before any method call? I have the similar situation and don't know what to do. If I get an instance of that object through constructor I get a dependency, because I cannot access to the private variable from the factory, if I put that variable in every method like a parameter it doesn't work either, because every method must work with the same object. If I put it in public property I'll get an exception if I try to use any method before assigning, so it isn't safe. Can you help me? What should I do? It seems to me that I have a design problem, but I don't know what to change.

    • IAmTimCorey
      IAmTimCorey  4 months ago

      It really depends on the larger situation. However, you can assign an initial value to a public property inline. Then, it will never be not initialized. You could also include a method that provides public access to the private variable if that is preferred.

  • hamada alashry
    hamada alashry 4 months ago

    would you sir publish a tutorial about dependency injection with both mvc and owin,please?

    • IAmTimCorey
      IAmTimCorey  4 months ago

      The TimCo Retail Manager will have DI in the MVC application eventually.

  • Iphone Polanco
    Iphone Polanco 4 months ago

    I can't Thank you enough for your videos Thanks Tim

  • Anass Ayed
    Anass Ayed 4 months ago +5

    I genuinely loved this video. Thank you!

  • Francis Yankey
    Francis Yankey 4 months ago

    Jim, have you got videos on the GoF patterns?

    • Francis Yankey
      Francis Yankey 4 months ago

      @IAmTimCorey I can't wait to watch them. There is soo much confusion out there. Will wait then. Thanks!

    • IAmTimCorey
      IAmTimCorey  4 months ago

      Not yet but they are on the list.

  • Francis Yankey
    Francis Yankey 4 months ago +1

    You are simply amazing! Excellent explanation bro.

  • Sammy B
    Sammy B 4 months ago

    Best video on DI. Thanks.

  • Michal Smola
    Michal Smola 4 months ago

    This is gold! Finally I can say I understand DI - thank you. And in case you don't overuse mouse only to make it easier for us to follow what you are doing (like when you were replacing commas with semicolons) - by pressing Ctrl+Left/Right you can move cursor through code much faster.

  • LONG LA
    LONG LA 4 months ago

    Thank you, Tim, your examples are very easy to understand the principles

  • Eric
    Eric 4 months ago

    Amazing 😍👌

  • Sagar Gourimath
    Sagar Gourimath 4 months ago

    This is beautiful

  • khaled nabil
    khaled nabil 4 months ago

    Very nice & informative
    Could you do videos about application architect applying solid with diff layers and best practises
    Thanks a lot

    • khaled nabil
      khaled nabil 4 months ago

      @IAmTimCorey
      Thank you 👍

    • IAmTimCorey
      IAmTimCorey  4 months ago +1

      I will add it to the list. Thanks for the suggestion.

  • vikash jha
    vikash jha 5 months ago

    Very nice

  • Argel Pamintuan Go
    Argel Pamintuan Go 5 months ago

    I caught the thought! Thanks Mr. Tim!

  • Abdul Khan
    Abdul Khan 5 months ago

    Very clear explanation, easy to understand. Excellent

  • sai kishore
    sai kishore 5 months ago

    Thank you sir, you cleared the confusion. Dependency Inversion (DI) is a principle and Dependency Injection is way to achieve DI. Now I understand it is similar that Liskov Substitution is a principle, and we use Covariance and Contravariance are ways to achieve Liskov Substitution.

    • IAmTimCorey
      IAmTimCorey  5 months ago

      I am glad that cleared it up for you.

  • Ricardo Valle
    Ricardo Valle 5 months ago

    Excellent video! very clear and easy to follow. Thanks Tim!

  • Hamed Javaheri
    Hamed Javaheri 5 months ago +1

    Excellent Explanation. Thank you very much Tim. :)

  • Ashutosh Srivastava
    Ashutosh Srivastava 5 months ago

    Thanks for this series. - Big fan of yours

    • Ashutosh Srivastava
      Ashutosh Srivastava 5 months ago

      IAmTimCorey can you please create a series on web API with .net core , ef core and implement design patterns.

    • IAmTimCorey
      IAmTimCorey  5 months ago

      You are most welcome. Thanks for watching.

  • Johan Vergeer
    Johan Vergeer 5 months ago

    Just like all other videos I've seen from you so far. Amazing. This is the first time for me everything comes together and makes sense as a whole. Thank you for that.
    I have heard and read about the SOLID principles a couple of times now, and when dealing with just (C#) code, it starts to make a lot of sense. Where I'm still struggling at this point is how these principles apply to IO. Like in databases or on screen. (Users these days don't really know how to work with a console.)
    As an example, what I would be really interested in seeing is how you would persist the models you created in the last two video's (employee and library) and what this would look like with MS Entity Framework. This would also apply for Java Spring, or other ORM's, but as you say, this channel focuses on C#.

    • IAmTimCorey
      IAmTimCorey  5 months ago

      If you stay tuned to my current series (the TimCo Retail Manager), you will see DI being used in a WebAPI and probably the WPF app too.

  • pepperplume
    pepperplume 5 months ago

    I watched your series, i find that SOLID principles attempt to tackle a different facet of programming that everyone will encounter, i believe the follow is a fair summary of these principles:
    S => is for changing existing code, to reduce any side-effects or bugs with the change
    O => is for adding new code, again to reduce any side-effects or bugs with the addition
    L => provides guidelines for Inheritance, which i hear no one defends anymore and is far less favored than composition
    I => provides guidelines for interfaces because everything will depend on interfaces
    D => is designing your software to be modular which is possible because everything depends on interfaces
    Its clear to see how these principles synergize with each other

    • IAmTimCorey
      IAmTimCorey  5 months ago

      I would say that is a mostly accurate assessment. I would disagree on LSP. LSP basically defines the "is a" relationship of inheritance. Composition doesn't affect that, it just reduces the amount of inheritance we do. In fact, LSP actually encourages composition because we were abusing inheritance before.

  • Barnum Castillo
    Barnum Castillo 5 months ago

    That moment when you realized that everything you have coded is wrong. Awesome explanation.

    • Barnum Castillo
      Barnum Castillo 5 months ago +1

      Thank you. I'm always learning and it is really encouraging when the professor is dedicated, keep the good work.

    • IAmTimCorey
      IAmTimCorey  5 months ago

      Here is my philosophy on that: it isn't wrong if it works. It may not be the best, and it may be something that could be greatly improved but I don't want you to get caught on "I'm wrong if I don't do it "perfect" the first time". Believing that is depressing and discouraging. Too many people believe that lie. We can all be better, but that doesn't mean we aren't ok where we are at right now. I'm glad you are continuing to learn and grow. Keep up the good work.

  • Muhamad Hanif Safwan Ab Razak

    i learned at my university what is interface, abstract and so on... but have no idea how and when to use them in my development (im a noob obviously), but after watch your SOLID videos, i finally have a strong understanding on how to use them. Thank you so much

  • Danilo Dvalmont
    Danilo Dvalmont 6 months ago

    I Finally understood the 'DI'. This is wonderful. Thank again, Tim!

  • Paul de Champignon
    Paul de Champignon 6 months ago

    Very helpful!

  • pepperplume
    pepperplume 6 months ago

    very well presented, i have one question, why do we keep the IPerson interface, IChore interface, and the other interface in the DemoLibrary project? Wouldn't it make more sense to have them in ConsoleUI project? Thanks again for this great content

    • IAmTimCorey
      IAmTimCorey  6 months ago +1

      I put them in the class library because the class library cannot depend on the UI project. If a class in the class library implements an interface, it has to have access to that interface.

  • Justin Hunt
    Justin Hunt 6 months ago

    Hi Tim, I totally get all 5 principals, thank you from the great tutorials. One question though. Is it possible to create an interface on a windows form class? I need to new up a form on my main class, but unable to refactor my form class into an interface (per VS). Thanks!

    • IAmTimCorey
      IAmTimCorey  6 months ago

      Yep. You can treat a form just like any other class. You can add an interface to it or even create a new class that inherits from Form and use that as a Form class (that gets a bit trickier because of the visual designer but it definitely is possible).

  • bricknose
    bricknose 6 months ago +1

    Wrapping all instantiation in a static factory feels like a code smell, especially since you haven't actually removed the dependencies on Person or Chore. You just created a new dependency on the static Factory, which in turn depends on the Person and Chore.
    Now accepting interfaces instead of explicit classes, especially in constructors that depend on other modules, is another thing, but this wrapping of Model instantiation? I don't see the point. And what if you want to pass a specific Logger and MessageSender to the Chore? Now you need two or more factory methods, or a complicated mix of optional parameters. Just seems like extra work for no benefit.

    • IAmTimCorey
      IAmTimCorey  6 months ago +6

      This is an extremely simple version of a factory. I didn't want to get too complicated in the factory pattern, nor did I want to bring in a tool to do it for us (like Autofac, which I cover in the Dependency Injection video). Those solve some of your concerns. As for not removing the dependency, no we didn't. But that's not the goal of the principle. It isn't the Dependency Elimination Principle, it is the Dependency Inversion Principle. We are inverting who depends on what. We are just moving dependencies around. At the end of the day, you have to depend on things. If your application has to send emails, at some point you will have to depend on a class that handles email. The trick is who drives the train? The UI, which has the ability to select which email system to use or the class library, which tells everyone else what it will be using? DIP says the former.

  • Free Debreuil
    Free Debreuil 6 months ago

    Very cool, different than the way I normally program but your example at the end of switching out the database framework is very good. Unit testing seems like it could be useful as well. Will try to integrate these ideas into my coding style.

    • IAmTimCorey
      IAmTimCorey  6 months ago

      Awesome! It can definitely be really helpful.

  • Athul R
    Athul R 6 months ago

    Nice videos of SOLID principles. These videos made me subscribe your channel :)

  • ValiRossi
    ValiRossi 6 months ago

    Fantastic. Great job.

  • Osman Y Mumcu
    Osman Y Mumcu 7 months ago

    I swear you are the best C# instructor I have seen so far. Thanks for the complete tutorial.

  • PhantomDragonStudio
    PhantomDragonStudio 7 months ago

    This was truly helpful! My biggest issue was thinking DIP and DI were one in the same.

    • Casey Strong
      Casey Strong 7 months ago

      IAmTimCorey If you ever do a Unity & Zenject tutorial video I would definitely watch it 😁

    • IAmTimCorey
      IAmTimCorey  7 months ago

      I'm glad you got this figured out.

  • femloh
    femloh 7 months ago +7

    By far the best explanation I have seen on dependency inversion. Thank you.

    • IAmTimCorey
      IAmTimCorey  7 months ago +1

      You are most welcome. Thanks for watching.

  • bo100nka
    bo100nka 7 months ago

    A question:
    What if i have a class that handles credit card payments and instead of "void" types (as you mostly used in this video), it actually returns let's say "TransactionResult" object? I am now confused in how will I instantiate the "TransactionResult" structure/class when returning from the "Pay()" method - should i also use "Factory.CreateTransactionResult()" instead of "return new TransactionResult{...}"?
    Because in my customer's app that i am developing, there are lot's of cases like this - returning simple "Model" objects while the "services" (classes) are injected via constructor of the owning class so i can unit test them.
    Could you/someone please share insights on this case?

    • IAmTimCorey
      IAmTimCorey  7 months ago

      It definitely depends on your situation. If you have a POCO model (one that just holds data basically - just properties), you can definitely new it up. Yes it is a dependency but as a type, not as logic. That is fine to have. Dapper doesn't use a factory either. It just creates the instances as needed.

  • Mohd Imadoddin
    Mohd Imadoddin 7 months ago

    Tim, thanks alot for videos.
    I see your creating emailer and logger objects and pass them in Chore class constructor. Why not create them in class itself? My class might depend on many objects and caller may not require all of them, like emailer object is not required in one method, then why creating objects when not needed?
    Thanks for clearing confusio।

    • Mohd Imadoddin
      Mohd Imadoddin 7 months ago

      @IAmTimCorey Thanks a lot Tim, great tutor.

    • IAmTimCorey
      IAmTimCorey  7 months ago

      Good question. The reason we don't create them in the class itself is because then the class depends on that specific implementation. For example, we would depend on log4net. If, later on down the road we wanted to change over to nLog, we would need to change each class that creates an instance of log4net over to use nLog. If we then move to a custom logging system, we have to do it all over again. This way, we can change it at the top level (where the class is getting instantiated) and it changes for everything.

      Typically, if you are not going to be using certain classes in certain circumstances and you want to avoid the cost of class creation (which is small but it is still something to consider), you can do lazy loading using a Dependency Injection system. However, I typically find that the cost of checking for that can sometimes be almost as much as creating a class instance so I don't always bother. It really depends on the circumstance.

      By the way, another great reason for DIP is that it allows for unit testing. You can test just your method without needing to also test all of the dependencies. You don't want your actual database calls or actual email system running every time you run a test.

  • Mohammed Hady
    Mohammed Hady 7 months ago

    This is by far the best tutorial about Dependency Inversion principle, it's the first time i really think i understand the concept. great work Tim

    • IAmTimCorey
      IAmTimCorey  7 months ago

      Awesome! I'm glad it finally clicked for you.

  • Jamin Benjamin
    Jamin Benjamin 7 months ago

    Finished with your SOLID videos and a few others about interfaces and generics. The way you SHOW the reasons to use SOLID and the fact that your examples are very similar to real life situations....it makes the content very easy to understand and retain in my mind. Can't thank you enough, I'm gonna watch ALL of your videos!

    • IAmTimCorey
      IAmTimCorey  7 months ago

      Awesome! I'm glad you are getting so much out of the content.

  • Mahmoud Abo Elnaga
    Mahmoud Abo Elnaga 8 months ago

    Thank you so much, simple and precious

  • X Academy
    X Academy 9 months ago +1

    Fantastic video, Tim. I've a question. In zenject we can inject dependecies to all interested in that dependecies types. But if I understood correctly it will be better inject to "top level types", and all other "more deep types" should get their dependecies from the direct higher level module, not from the project root entity am i right?

    • X Academy
      X Academy 9 months ago

      Thank you!

    • IAmTimCorey
      IAmTimCorey  9 months ago +2

      All dependency resolutions should come from the root. That way you don't have to have multiple places where dependencies are derived from and so that you can universally make changes that affect your entire application.

  • Wttftyh Gytyf
    Wttftyh Gytyf 9 months ago

    I have to be honest Interface Segregation is my favorite by far! But I don't know its kinda hard to apply all 5 principles when working with EF, like a repository pattern keeps the code clean and shorter for an extent. I am gonna have an interview like next week and I already knew about solid, but your tutorials for sure adds a more clarity for what I already knew. As a next junior what is your advice for me when talking about SOLID, should I keep it simple? Like trying to come up with even simpler examples on interview for each principle? practice them in visual studio and then explain them on paper?

    • IAmTimCorey
      IAmTimCorey  9 months ago +1

      Keep it simple is almost always good advice. I would recommend talking more about the purpose of them (if the questions allow it). Knowing why you should use something is so much better than knowing the exact specifics.

  • laskalex
    laskalex 9 months ago

    Very clear explanation, ty.

    • IAmTimCorey
      IAmTimCorey  9 months ago

      You are most welcome. Thanks for watching.

  • Benjamin Anderson
    Benjamin Anderson 10 months ago +1

    This changed my life. Thank you.

  • MUHAMMAD ADIL Khan
    MUHAMMAD ADIL Khan 10 months ago

    Thank Tim could be please share the unit testing link that you discussed
    in the end.

    • IAmTimCorey
      IAmTimCorey  10 months ago +1

      Not sure what unit testing link you are talking about. I do have two unit testing videos on this channel you could watch, if that is what you are referring to.

  • Lalita Patil
    Lalita Patil 10 months ago

    These video are really helpful to understand SOLID principle.Thanks a lot.

  • GravyTrain
    GravyTrain 10 months ago +1

    You are a great teacher! Thank you so much.

  • Yatish Bhavsar
    Yatish Bhavsar 10 months ago +1

    As always simple & elegant. Thank you for the video.

  • Afshin
    Afshin 10 months ago

    great video

  • Antonio Vitas
    Antonio Vitas 10 months ago +2

    finally, I understand this principle...thank you Tim, as always!

  • alb12345672
    alb12345672 10 months ago

    tl;dr:
    "new" is the new 3 letter word!

    • IAmTimCorey
      IAmTimCorey  10 months ago

      That misses a bit of the nuance but basically. :-)

  • FacePalmProductions
    FacePalmProductions 11 months ago

    "Coding games is easier than you think! You know-"
    "NO. YOU KNOW!? I SHOULD PUNCH YOU SQUARE IN YOUR SMUG FACE YOU ****" :D
    I hate that ad.... so... so much..
    I love your tutorials Tim. Spot on.

    • IAmTimCorey
      IAmTimCorey  11 months ago

      I'm glad you enjoy the tutorials. Sorry about the ads. I'd love to turn them off but they provide a significant enough income that I need to leave them on (for now).