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

Share
Embed
  • Published on Apr 23, 2018
  • 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 fifth entry in the famous SOLID principle. The D stands for Dependency Inversion Principle. This isn't the same thing as Dependency Injection but it is what powers it.
    Newsletter signup (with exclusive discounts): signup.iamtimcorey.com/ (your email will be kept safe and you will not be spammed).
    Source Code: leadmagnets.app/?Resource=DInSOLID

Comments • 280

  • Desi Trump
    Desi Trump 4 hours ago

    चोर class

  • Armando Avila
    Armando Avila 7 days ago

    Thanks, Tim. This video is by far the best I've watched on this topic, I almost got it, but there is one thing I didn't understand, I came from a Java/Kotlin background. I didn't get why you made an IPerson and an IChore interfaces and then you instanciated them with the Factory that returns only Person and Chorer classes, not IPerson and IChore ones. Can you help out? I've never used an Interface in that way.

    • Armando Avila
      Armando Avila 2 days ago +1

      @IAmTimCorey thanks for the response. Now I can see whare I was wrong, but yeah, I'll watch your video on interfaces, just to leave no place for misunderstanding. Great videos man, keep it up.

    • IAmTimCorey
      IAmTimCorey  4 days ago +1

      You cannot instantiate an interface. You set a variable's type to be an interface type so that you can store an instance of any type of class that implements that interface but you have to store an actual concrete type in that variable. This gives you flexibility. I have a video on Interfaces that might help.

  • Frank Yu
    Frank Yu 12 days ago

    Thanks for your video, that is good explain

  • Haitham Shaaban
    Haitham Shaaban 16 days ago

    Very clear and detailed, Thanks Tim.

  • Ashutosh Srivastava

    Please create a video on CQRS pattern

    • IAmTimCorey
      IAmTimCorey  29 days ago

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

  • Peter Lustig
    Peter Lustig Month ago

    Hi Tim, you bring a light to me. I have a way better understanding of these principles. Greetings from Berlin, Germany.

  • faizal vasaya
    faizal vasaya Month ago

    3 shots to the approach for explaining Dependency Inversion. It goes and sits into our heads and stays there for a long time.
    Keep up to good work Tim.
    You are really making it easy to learn software development.

  • Björn Böhnert
    Björn Böhnert Month ago

    I like that you explain it in the bigger picture. That's a way I can easily understand through your great video. I am very glad that you take your time for this great YT channel. Have a good day!

  • Kevin Searle
    Kevin Searle Month ago

    Hi Tim,
    Just finished watching your series on SOLID which I have found very useful so thanks for that.
    I think I missed something in this, the DI video.
    For the logger and the messagesender you passed interfaces as parameters to a constructor instead of using the centralised Factory class.
    What was the reason for this?
    Is this an illustration of two separate techniques for achieving DI or something you were forced to do for separate reasons.
    Could Person and Chore conform it DI using a constructor with interfaces passed in??
    Could logger and messagesender have used the centralised class?
    Thanks again

    • IAmTimCorey
      IAmTimCorey  Month ago

      I used interfaces so that the "bottom-level" classes did not dictate what they depended on. They just asked for something that implemented the interface. Then, the factory could provide what it decided when it was needed.

  • Linkario86
    Linkario86 Month ago

    It keeps complaining that the interfaces are less accessible than Factory.CreateWhatever()

    I can't figure out why that is

    • Linkario86
      Linkario86 Month ago

      @IAmTimCorey Omg! of course! thanks Tim. Sometimes it's the obvious mistakes ':D

    • IAmTimCorey
      IAmTimCorey  Month ago

      It sounds like you didn't set your interface to public.

  • Linkario86
    Linkario86 Month ago

    Isn't Emailer depending on Person at the start, since it is in the Emailers Parameter?

    • IAmTimCorey
      IAmTimCorey  Month ago

      That is correct. Emailer depends on IPerson. That's the inversion. Usually, Person depended on a specific emailer. Now the caller can decide which emailer to use at runtime.

  • Robert Breedt
    Robert Breedt Month ago

    You: "That's gonna take us probably... 6 months to do."
    Boss: "You have a weekend."
    Story of my life at my first company...

  • Jay Giles
    Jay Giles Month ago

    These are excellent 👍 one question using the factory class if I need to create a list of person I.e. List how would I do that without breaking DI?

    • IAmTimCorey
      IAmTimCorey  Month ago

      Great question. Models don't necessarily come from the factory. That's part of the reason why separating logic from your models is a good idea. For instance, when I use data access, I usually use Dapper. It builds a List for me. I don't run that through the factory.

  • Spaghetti Papa
    Spaghetti Papa Month ago

    I genuinely don't understand how this isn't just an over-reliance on interfaces. It seems to me that writing versatile base classes is incontestably more efficient and less error-prone than something like this. I'm having a really hard time understanding how anything in this example wouldn't have been substantially simpler and more reliable using class inheritance than interfaces.

    • IAmTimCorey
      IAmTimCorey  Month ago +1

      Inheritance is more often the wrong answer than the right one. Inheritance is not for just code sharing. It signifies a relationship (the "is a" relationship). So a car is not a truck even if they both have an engine. Even if you inherit them both from a common base class (MotorVehicle maybe?), you still run into issues with a boat. You could say that is a motor vehicle too except you also have sailboats. Now you have to figure out how to double-inherit (not really possible) to get the qualities of a boat and a motor vehicle into one item. So, that's the problem with thinking inheritance is the solution.
      As for the Dependency Inversion Principle in general, it does more than just share code. It inverts who depends on what. That way your class library can say "I am going to log this message" and have no clue which logging system you chose (which is exactly how all .NET Core applications do it now). Also, when you go to write unit tests, it is easy to swap out one implementation for a mocked version and eliminate your external dependencies so that you can test just one unit of work and not create some messy integration test.

  • Sachidanand Upadhyay
    Sachidanand Upadhyay 2 months ago

    your content is very strong to understand the concept, I would like to suggest if you bit brief with live type project or content. Best Video I ever found

    • Sachidanand Upadhyay
      Sachidanand Upadhyay Month ago

      @IAmTimCorey ASP.net MVC or Web Api N-Tire Architecture. can you explain or can i get good source code ? how much i have to pay?

    • IAmTimCorey
      IAmTimCorey  2 months ago

      Thank you!

  • Shawn Mofid
    Shawn Mofid 2 months ago +5

    There is no replacement for video content and this type of platform. You get to watch it any time, any where, and as many times as you want to and you can. So glad to be alive in this time and age. Thanks for the content Tim. I leaned a lot.

    • IAmTimCorey
      IAmTimCorey  2 months ago +1

      You are most welcome. Thanks for watching.

  • Frud
    Frud 2 months ago

    You got a new subscriber. This was an excellent explanation. Thank you!

  • Peter Sabry
    Peter Sabry 2 months ago

    i'm pretty confused
    so in order to make my application structure decoupled, i should abstract every class, right?
    does that violate YAGNI?
    beacuse i'm sure that some classes in my application won't be swapped away anyway as it does only one desired job
    i tried to add a database abstraction layer which helped me with mocking which is good

    • IAmTimCorey
      IAmTimCorey  2 months ago +1

      The other part is testing. If you don't loosely couple things, you can't pull them apart for testing. I've got a video that shows you why this is important: thexvid.com/video/DwbYxP-etMY/video.html

  • KousiK Chatterjee
    KousiK Chatterjee 3 months 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  3 months ago

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

  • Kevin A
    Kevin A 3 months 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 3 months ago +2

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

  • ionicafardefrica
    ionicafardefrica 3 months 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  3 months 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 3 months 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 3 months 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 4 months ago

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

  • Toine Koene
    Toine Koene 4 months 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 4 months 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 4 months 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  4 months 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 5 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  4 months ago

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

    • Ninh Luyen
      Ninh Luyen 5 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  5 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 5 months ago

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

  • IC
    IC 6 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 6 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  6 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 6 months ago

    Really valuable Video. Well done Tim Corey!

  • Amon Fesef
    Amon Fesef 6 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 6 months ago

      @IAmTimCorey , thank you!

    • IAmTimCorey
      IAmTimCorey  6 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.

  • Антон
    Антон 6 months ago

    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  6 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 7 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  7 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 7 months ago

    Thank you!! very clear!

  • Francis Yankey
    Francis Yankey 7 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 7 months ago

      @IAmTimCorey I see

    • IAmTimCorey
      IAmTimCorey  7 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 7 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  7 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 7 months ago

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

    • IAmTimCorey
      IAmTimCorey  7 months ago

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

  • Iphone Polanco
    Iphone Polanco 7 months ago

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

  • Anass Ayed
    Anass Ayed 7 months ago +8

    I genuinely loved this video. Thank you!

  • Francis Yankey
    Francis Yankey 7 months ago

    Jim, have you got videos on the GoF patterns?

    • Francis Yankey
      Francis Yankey 7 months ago

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

    • IAmTimCorey
      IAmTimCorey  7 months ago

      Not yet but they are on the list.

  • Francis Yankey
    Francis Yankey 7 months ago +1

    You are simply amazing! Excellent explanation bro.

  • Sammy B
    Sammy B 7 months ago

    Best video on DI. Thanks.

  • Michal Smola
    Michal Smola 7 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 7 months ago

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

  • Eric
    Eric 7 months ago

    Amazing 😍👌

  • Sagar Gourimath
    Sagar Gourimath 7 months ago

    This is beautiful

  • khaled nabil
    khaled nabil 7 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 7 months ago

      @IAmTimCorey
      Thank you 👍

    • IAmTimCorey
      IAmTimCorey  7 months ago +1

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

  • vikash jha
    vikash jha 8 months ago

    Very nice

  • Argel Pamintuan Go
    Argel Pamintuan Go 8 months ago

    I caught the thought! Thanks Mr. Tim!

  • Abdul Khan
    Abdul Khan 8 months ago

    Very clear explanation, easy to understand. Excellent

  • sai kishore
    sai kishore 8 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  8 months ago

      I am glad that cleared it up for you.

  • Ricardo Valle
    Ricardo Valle 8 months ago

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

  • Hamed Javaheri
    Hamed Javaheri 8 months ago +1

    Excellent Explanation. Thank you very much Tim. :)

  • Ashutosh Srivastava
    Ashutosh Srivastava 8 months ago

    Thanks for this series. - Big fan of yours

    • Ashutosh Srivastava
      Ashutosh Srivastava 8 months ago

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

    • IAmTimCorey
      IAmTimCorey  8 months ago

      You are most welcome. Thanks for watching.

  • Johan Vergeer
    Johan Vergeer 8 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  8 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 8 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  8 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 8 months ago

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

    • Barnum Castillo
      Barnum Castillo 8 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  8 months ago +1

      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