Angular dependency injection in depth – Dependency providers (2021)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hello guys! My name is Dmytro Mezhenskyi. We continue to explore the power of Angular dependency injection and thanks to my two previous videos we already know how angular resolves dependencies and how we can control this process by using resolution modifiers like @Self(), @SkipSelf() @Host() and @Optional(). In today's video I will show you how to use dependency providers which allow you to control how angular should create the instances for provided dependencies. We're going to cover today the next dependencies providers like useClass, useExisting, useValue and useFactory and also we will cover a little bit injection tokens today. as always this video was split into different sections and time codes to the sections you can find in video description. So don't forget to subscribe to my channel right now and we are getting started with dependency provider called useClass. So guys... let's quickly recap how do we provide dependencies. So... we do it either in providers property of components or directive or model or inside injectable annotation, right? so now let's imagine that we have a next case: we developed another experimental logger service, right? and we would like to test it with some certain component before to apply it globally in the application and because we want to kind of replacement of the logger on the fly we need to be sure that they both have the same api, right? and for this we need to create appropriate interface which our loggers will be implementing so i will run `ng g i logger` which means ng generate interface logger and it will generate an empty interface for us let's open this file and let's say that it should have a property prefix which is a string and the method log which takes a message with type string and it returns nothing so it is void then we implement this interface for logger service and now let's create our experimental logger so i will run ng generate service experimental logger and then we go there and implement our logger interface and then we will add necessary fields and also the lock method so this service will do the pretty much the same thing but it will have the it will have the string which contains this experimental keyword okay so far so good now we can play around with dependency providers so as i said earlier we would like to apply our experimental logger only to app component and its children so only node injector hierarchy would use this and and also we are not allowed to change our constructor because i don't know let's assume that components come from the i know separate library which has been created by our colleagues from another department and they're all in vacation so nobody can adjust them and this is where use class could be a good fit we just have to slightly modify our providers property and instead of directly provided i just create an the object which has at least two properties and first one is provide and we say that provide our logger service and the second one is our use class dependency provider and as a value we add a reference to our new experimental logger service so it means that when angular will create an instance of this logger service in app component injector it will not create an instance of logger service but it will create an instance of the class which we defined in the use class angular will literally do something like return new experimental logger service and provides its dependencies if it if it is and now if we save it and go to our browser and check the console we will see that the message is coming from experimental logger service which means that use class was executed correctly also you can do the same configuration inside injectable annotation you just need to define it somewhere here so like this and now because we have provided in root everywhere in the application will be used implementation of this new service of course if you don't override it somewhere in child injector like we do right now in the application component okay that was used class provider which allow you to provide alternative class implementation but use class has one let's name it feature and it creates a new instance of the class and if as example i would like to inject experimental logger service into our constructor like this and it will be separate instance and our logger service here will not be the same instance of this one so it would not be a singleton anymore and i can prove it i can just console log it here i put the message if both loggers are equal and i will just compare them now if we go to the browser we will see that it says false but what if we want to create just an alias for the experimental logger service so i would like to use already instantiated service which leaves now in the root model injector because we use provided in ru provided in root right and in this case we should use use existing dependency provider and doing this we tell angular to not create a new instance for the service but grab already instantiated one so in our case it would be taken this experimental logger service which already exists in the root model injector alternatively you can use use existing provider inside the injectable annotation if you prefer to use three shakeable services now let's go back to our app component it could be also the case that you already have an instantiated and properly configured object and you do not want angular to create it and use just all the existing object it could be some let's imagine some super legacy logger which is not a class but just an object with some similar interface like i don't know this one and if we provide it to use existing provider it will fail because it is not injected and angular will be trying to will be trying to find dependency for the object object use class also would not work because uh it uses operator new in order to create an object and you cannot call the operator new against the object literal so there should be another way and in this case you have to use use value provider and we can provide our legacy object as a value and now angular will assign this object to this provider very often this use value is being used in tandem with injection token and when you want to inject a non-class element let's say some string or config object as example and i would like to show you uh some use case for this injection token and i'm going to create some global config for our application so let's just create a separate file and create there first of all the interface which describes uh our config and it will have only one property called experimental enabled which is boolean and here below there will be an application config which is which is injection token with type app.config then we have to provide a value to this token and you can either do it is as we did it before in providers properties somewhere in app model because it supposed to be a global config right and we can add object here and then provide and use value like this but i will use another tree shakeable way i just go back to config token and here as a second parameter i can path an object and like with the services i can say provided in root and then i will use factory in order to provide a config and it will enable experimental features and after this you can inject it in your constructor somewhere in i don't know service maybe and you can use the inject annotation for this i will console lock it in constructor for now and if i go to to the browser and reload the page i can see that my config was injected okay cool i will remove it so far from it and just few words about injection token and why do we need it if you saw my first video about dependency injection we built there some dependency injection prototype and here we had a map where the key was a class reference and the value its instance and because we inject not a class we cannot use class reference as a key but we need to have some key anyway otherwise angular cannot understand how to resolve it interface also will not work because interfaces are not existing at the runtime and this is where injection token can help us and the value of injection token will act as a key in this case and i hope it is uh clearer now and we can move forward the last dependency provider is use factory and this provider is very convenient if you do not know which service to provide in advance and this could be known only during the run time and this is quite often happens when you need to configure provider based on the value from another service or dependency injection token so let's use our app config which we created and we will resolve correct logger for our application depends on if experimental features are enabled or not so i will use this provider use factory the factory is going to be just a function empty so far then we know that we have a dependency on our app.config so we have to provide it and we will do it by using depth property and we provide app config here inside the array and once we have done we can access it as a function argument here and now we can check if experimental feature is enabled we will use experimental otherwise we use our logger service all right now we can save it and check in the browser if it works i reload the page and we can see that experimental logger was involved so let's try to change it i turn off the experimental feature and then i go back to the browser and we can see that now logger service logged the message if some of your services have dependency on let's say http client yeah why not you can provide them all in depth array and then you can inject this in your service constructor so let's assume that our experimental logger does some http calls yeah like this and then we have to inject it inside the class constructor here we go and of course do not forget to import http client model into app model otherwise your app will fail so this is how you can use factories in order to make your providers even more flexible and the last thing for today i would like to show you is the difference between use value and use factory it is very often developers are confused by this too especially who saw some construction like this so in use value also could be provided a function so let's try to console.log what is our logger currently so we can see that this is our experimental uh logger instance right and now let's try to change it to the use value and try to console.log it so do you see instead of instance of the service we get just a function as it is when use factory calls this function and uses their return value as the value for the token so we can say that use value has a static nature when use factory has dynamic one and this is pretty much it about the providers and the one reminding things is uh property multi-true but i will do this in another video which will be released somewhere in one week and yeah there i will show you some real case where you could apply this feature okay guys that was it for today i hope you enjoyed this video and now you have better understanding what is dependency providers in angular and which problems they are solving of course i would like to hear your feedback in comment section and hit thumbs up if you like my videos and don't forget to subscribe to my channel because more interesting and in-depth angular topics are coming and as always i wish you productive week take care and see you in the future you
Info
Channel: Decoded Frontend
Views: 19,667
Rating: undefined out of 5
Keywords: angular dependency injection in depth, angular 10 dependency injection providers, angular dependency injection factory, angular dependency injection tutorial, angular 10 dependency injection, dependency injection in angular 10, webdevelopment, angular services and dependency injection, Angular 10 tutorial, angular
Id: T1xmCC4y3xo
Channel Id: undefined
Length: 17min 19sec (1039 seconds)
Published: Sun Oct 11 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.