Dependency Injection | Comparison between DI, IoC and DIP | Dependency Injection Unit Testing.

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hello friends, welcome to programming concepts my  name is amit and in this video we will learn the   basics of dependency injection with the help of  same example, we will learn inversion of control,  dependency inversion principle and dependency  injection. We will also answer the very basic but   most confusing question which developer have? that  is, How dependency injection help in unit testing?  we will also explore how web.config can  be your best example in interview, when   explaining about inversion of control and  last but not the least we will also answer   why should we use dependency injection when  we already have dependency inversion principle.   so dependency injection itself is not difficult to  understand you must have heard dependency injected   by a constructor, method, or property and that's it  you are done the real problem arise when you start   comparing different terms available in the market  in the IT industry like IOC inversion of control   dependency inversion principle DI or IOC container  this is the time when we start doubting ourselves   why should we use dependence injection how  they are different from each other etc etc   we will compare and cover every aspect in  this video and by end of this video you will   get all your answers all right so let's begin  before moving forward it is really important to   understand what dependency and tight coupling  is let's say for example we have a class B   and this class B has some dummy method and that  will do something that's it our class B is ready   then we have a class A where we  declare the variable of classB   and within the constructor of classA we instantiated the object of classB   so if we created some class that must  be responsible for doing something   so for that let's say classA has to perform some  task let's name it task1 and here we do something   and the activity of task1 is dependent on class B So we call the method of classB dummy method   and then again we will do something within classA that's it simple very straightforward example   but if you can see that task 1 is dependent  on dummy method of class b so it has some   kind of dependency on classB and when we  initialize the object of classB within   constructor that is tightly coupled with classB  for example if there is any change in classB it   definitely going to impact classA so this is what  dependency and tight coupling is in about, so all   these concept dependency, tight coupling, dependency inversion principle IOC, dependency injection these   concepts are really simple but the basic problem  with developers to understand this concept is   when we start our career we generally have full  control over complete application so we act as a   full stack developer, Right? Where we own UI, we own  services, we own business logic, database and all   just in case you are also in a similar kind  of project or your team is in a similar kind   of project where you own everything so we just  wanted to make an assumption before going forward   so for the rest of this video, I would request  you to assume that you don't own even a single   other class in your project. Simple? Although this  assumption or the statement seems pretty easy but   believe me for full-stack developers or developers  like me who started their career with complete   ownership of each and every module even to  assume we don't have access to any other class is   extremely difficult. So, I would request you to make  that assumption in your mind for the rest of the video. In that note let's suppose we have a project  requirement with us and the requirement is   like create module to log errors in text file to  achieve this let's say we will first create class   library project and first class of this project  will be log to text and this will be managed   by teamA, second class will be business logic  class and suppose this will be managed by teamB   so we will create another project and that  project will be a console application project   and again this will be a dummy client who will use  our project, our organization project or services   so here we are creating a class library project so  this console application project will consume our   class library project, the DLL and assume class library  project will be used by similar multiple clients I already created both the projects in visual  studio. Let's see, this is our empty class library   project and the next one, this is our console  application project so let's get back to slide   and create both the classes so public class log to  text bracket open public void log string message   so console.writeline message bracket close bracket  close and your class is ready. So here just assume   that instead of console.writeline in real world  it will log your message into a some kind of   text file. Let's create another class so public  class business logic bracket open log to text   let's name it underscore obj log public business  logic bracket open we created a constructor here   and again obj log is equal to new log to text public void dummy method string message  and this method will consume log to text   method which is log, bracket close so if we look  at this code this project is similar to what we   had shown you in the slide of dependency  and tight coupling so here you can see business logic is dependent on logtotext class All right, also business logic is tightly coupled  with log to text because we created the object   within business logic constructor so the question  is, is there any problem with this implementation   because we already following such kind of approach  since we are doing a development. Correct? so in   general not not a big problem if you have control  over all the classes and your project is small   let's see the problems one by one so the first  problem is in case of change in dependent class   log to text we need to make changes in all  places where we are referencing this class   okay let me just copy and  paste the code in visual studio so open a class library project right  click on the project add a class and let's name it businesslogic.cs   click on it so let's copy and paste  our code in this particular file so this is similar code which we have seen  in the slides we have a business logic class   we have a log to text class so the problem  statement was if there is any modification   in log to text class then it will impact all  the classes which is referencing this class   all right so for example this class as of  now we have a default constructor which is   created by dotnet itself let's create another  constructor public lock to text bool is valid   so what will happen now it will start impacting  business logic class and in this project you know   seems really easy that you can modify the business  logic class but in real-world that log to text   class might be used by, you know, multiple projects  where you don't have much control over them so   this is one of the problem that we need to modify  all the dependent classes who are using our class   let's get back to the slide and let's say in case  of future upgrade, our product starts supporting   logging the logs into the database. All right!!  so again we need to make modification in all   our dependent classes let's get back to the code  so here you can see that log to text file is   hard coded within business logic class so again  all the classes who are referencing log to text   we need to change the name to log to sql database  or something to make it easy let's create another   class let's just copy log to text class  and let's rename it log to sql database so now if business logic class have to consume  log to sql database class they need to rename   log to text class with log to sql database  class and that log to text class might be   used in 1000 other classes. All right? so you  need to rename them again in all the classes   so if you're from a dot-net background or  using some powerful IDE like visual studio   then you must be wondering what's the problem in  renaming log to text class so if I have to rename   log to text to log to sql database then what we  can do, we can just right click on log to text   click on rename and rename as per our convenience  like log to sql database and then what i will do   i will click apply so that will rename log to text  to log to sql database across application. Correct? If you are thinking in that way then you are still  in full stack developer mode. Remember I asked you   to make an assumption that you don't have control  over other classes, correct, so you can make   modification in business logic class there might  be a possibility that other class which you don't   own. Another possibility is that this particular  dll class library vendor so this particular dll   might be used by some other project where you  don't even have access to their code correct   so let's see how we can overcome these limitations   for that first we need to understand what  inversion of control is? so let me read out   the definition then we will understand what  actually the concept is so inversion of control   is a design principle remember it is a principle  not a pattern, is a design principle   used to invert different kinds of control in  object-oriented design to achieve loose coupling   the main objective of inversion of control  is to remove dependency between objects of   an application which makes the application more  decoupled and maintainable inversion of control is   a principle which means it is a general guidelines  and end user can choose the way how they wants to   implement it all right so let's use this principle  to refactor our code so this is our existing code so let's create another class public class factory   and this class have one static method  public static log to text get logger   and it will simply written log to text  object that's it our factory class is ready   now we need to refactor our business  logic class so public class business logic   log to text underscore obj log public business  logic this is the constructor bracket open so   now there is a change instead of creating new log  to text let's use the factory class to provide us   the instance of log to text class so obj log is  equal to factory dot get logger other code will   remain the same public void dummy method string  message bracket open underscore objlog.log message   that's it so if you look at the code closely this  will resolve the problem statement one in case of   change in dependent class log to text we need  to make changes in all the places where we are   referencing this class now if multiple classes are  using log to text class with a default constructor   and there is a change in constructor then we only  need to make modification within our factory class   so that will be our central point so what we  had done here we just inverted the control   previously business logic class has control  to create the object of log to text class   now we just give this responsibility to another  class, Iknow this is a very basic example of   IOC inversion of control and that too is  not implemented properly but that's what   inversion of control is all about we are just  inverting the control just in case if you have   any confusion let's cover another example of IOC  another very good example I can think of IOC is   connection string in web.config. what?  connection string in web.config but how let's see a practical example  of it let's get back to our code   let's create this method within business logic  class so public string get connection string   and that will return configuration manager  press ctrl dot to add the reference   dot connection strings and let's name  it myconstring dot tostring that's it   so this connection string my con string  is not present within my dll i   haven't specified it anywhere correct so  let's rebuild our class library project and let's get back to our console application I  already added the reference of that class library   project and if you can see in the app.config  I already specify one connection string with   the name my con string which is there in my  class library project and here it is. All right let's go to program.cs file and within  static void main method let's write new   business logic ctrl dot to add the reference dot  get connection string that's it our code is ready   now if I run this program what do  you think what would be the output   so if you guessed that it will  return the connection string   which is present in the console application our  client application then you are correct all right   but how it is possible so that's what  internally inversion of control is all about   so ideally we should define the connection string  and everything within our class library project   but what we want we want that it should be  provided by our client so my business logic   class is not owned the responsibility to have the  connection string right so that responsibility   has been provided to the clients now I hope you  understand the concept of IOC slightly better   just give the responsibility to someone else  who can manage it better than you alright let's get back to the slide so with the current implementation we are able to  get rid of problem one but the problem statement   two still persist let's learn another concept  before getting rid of this problem statement   and the new principle is dependency inversion  principle so let me read out the definition I   already covered dependency inversion principle  in a great detail so you can watch that if you   are not much aware of dependency inversion  principle i will share the link in the description   so the dependency inversion principle states that  high-level module or classes.. high level should not   be dependent on low level modules or classes both  should depend upon abstraction also abstractions   should not depend upon details but details should  depend upon abstractions, again i am assuming you   have basic idea of what DIP is just in case you  are completely unaware of what DIP is I would   strongly recommend you to watch that video and then  get back to this video all right so let's refactor   our code according to DIP so first create an  interface public interface Ilogger void log   string message then create our log to text class  public class log to text and that class will be   inherited from Ilogger class next is method public  void log string message console.writeline message   and that's it logtotext class is also ready  next is factory class so public class factory   public static ilogger get logger so instead of  returning the exact class name we are returning   the interface return new log to text class  and that's it our factory class is also ready   our final class is business logic class so  public class business logic now again instead of   log to text class we are using i logger  interface so ilogger underscore obj log   public business logic and again underscore  obj log is equal to factory.getlogger so the   responsibility is still with factory class and  rest of the code is same public void dummy method   string message underscore objlog.log message and  that's it our business logic class is also ready   so this code will solve our problem statement 2  as well for example in future if we need to save   these logs into a database so when the new class  will be created so that will also inherit it from   logger interface so in future if business  logic or similar other class wants to use   log to sql database instead of log to text we only  need to make modification within our factory class   like this and that's it everything is  perfect right so all the scenarios and   all the problems has been covered  but there is still one problem   like the control to select logger class  is still within our business logic dll   right and that dll will be consumed by  our clients and our client project console   application project is still not in control to  select which logger class they wanted to use   so here is the expectation just like we had  specified connection string in our main project   console application project and our dll picked  it dynamically can't we create such mechanism   with a code as well so that our end user is in  control to select which logger they want to use   obviously depending on the scenario  you can use if an else statement   to achieve this but let's see  how to do it in an efficient way   let's learn dependency injection so dependency  injection is a design pattern that used to   implement IOC so IOC was a principle DI is a  pattern it allows the creation of dependent   objects outside of class and provide those  objects to a class through different ways   using DI we move the creation and binding of  dependent objects outside of the class that   depends on them so there are different types  of dependency injection available like you can   inject it by a constructor you can inject it  by property and you can inject it via methods   so let's refactor our class so  our interface will remain the same   log to text class will remain the  same there is no need of factory class   let's refactor our business logic  class so public class business logic   let's create an object of i logger i logger  underscore obj and within the constructor specify   the parameter as i logger let's name it underscore  logger and assign this injected ilogger object   to our local variable next is public void dummy  method string message objlog.log message etc etc   so this is what we call dependency injection via  constructor so because we injected dependency of   log to text file via our constructor now  if end-user or the client can use it like   new business logic new log to text bracket  close dot dummy method my log message so   that will work the same way  it was working previously let's see how it will work in our code so let's  copy and paste the code of our dll class rebuild   that dll and within our console application just  write new business logic bracket open new log to   text bracket close again close dot dummy method my log message and that's it just run the application and eventually, it will print my log message   so we successfully injected the  dependency of log to text class   in future if client want to use a log to sql then  instead of using log to text class they can use   log to sql database class so the control is with  the client not within our dll or the jar file   let's get back to the slides and see the benefits  and drawbacks of this approach so the benefits is   it provide loose coupling it will help in  unit testing drawbacks are no compilation   time IntelliSense and chances of runtime error  but wait help in unit testing but how let's see   how this approach will help us in unit testing so  let's see the code without dependency injection   and here it is and let's assume that we need  to add few more parameters to log to text file   so let's assume this log to text file has couple  of parameters like id and name the only problem is   that id we need to fetch it from database and  that name we need to fetch it from client api now because the responsibilities with class  itself you cannot provide dummy data to this class   right so let's say your manager say provide me the  unit test report with logger with id 1 logger name   is pro. developer.. but client database and its  API is not available for any reason how does   it matters i only want a unit test report and boom  you're stuck but if you had used the dependency   injection approach then unit testing will be quite  easy because the responsibility is someone else   into the client so we can simply test it with obj  id is equal to 1 obj name is equal to pro and then   business logic objBL is equal to new business  logic and done that's it a unit testing is   completed and independent of database independent  of any API I hope these simple examples will help   you to understand what DI is their significance  and how it is different from IOC and DIP   so that's it from this video if you have any  query do ask me in comments. thanks for watching
Info
Channel: PRO Concepts
Views: 5,863
Rating: undefined out of 5
Keywords: ProConcepts, PROConcepts By Amit, dependency injection, dependency injection c#, how dependency injection helps in unit testing, how dependency injection helps unit testing c#, dependency injection vs inversion of control, dependency injection vs dependency inversion principle, di vs dip vs ioc, IOC container, why should we use dependency injection, benefits of dependency injection, dependency injection and mocking, dependency injection mock objects, why DI when we have DIP, amit
Id: tKIuAV2dEl4
Channel Id: undefined
Length: 25min 7sec (1507 seconds)
Published: Wed Jun 02 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.