How to Use Dependency Injection in ASP.NET Core

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
asp.net core has support for the dependency injection design pattern and in this video we'll show you how to implement it into asp.net core now dependency injection is when you inject an instance of an object into another object that it relies on in asp.net core there are three service lifetimes that are relied on independence injection we'll show you what they are how they work and how to implement them we'll also show you some of the common errors that you might get when using dependency injection in asp.net core and how to resolve them now for more asp.net core coding tutorials visit roundthecode.com subscribe to our youtube channel at youtube.com forward slash round the code and follow us on twitter it's at round the code join the round the code discord server ask your asp.net call question and get our community to help solve your issue go to roundthecode.com forward slash discord before we start implementing dependency injection let's have an overview of how it works and the different service lifetimes so we have a singleton lifetime any objects that are registered using the singleton lifetime will be initialized until the application stops then we have the scoped lifetime in the case of an asp.net core application a scope is initialized when a http request is made and is disposed of when the http response has been returned however it is possible to explicitly define when a scope begins and when a scope ends finally we have the transient lifetime we have taken the example of injecting a service registered with the transient lifetime into a controller then injecting the same service into a view regardless of where a service with a transient lifetime is injected it will create a new instance every time it's injected so in order to test dependency injection we're going to set up an asp.net call web application and implement it within that now i've got visual studio 2019 open in front of me so let's go ahead and create a new project let's select asp.net call web application and let's give it a name of around the code dot di which stands for dependency injection select asp.net call web app model view controller and press create this will now set up our project for us okay so our project is set up what i want to do now is i want to right click on the solution we can go to properties but now i'm going to go down to debug i'm gonna select project i'm gonna untick launch browser and select the app url to be localhost 4000 and save it okay so let's give that a run and see if it's actually going to work for us okay so our application is now working let's just see if it's going to work for us so let's open up chrome localhost 4000 colon 4000 that's where we're running our asp.net core application let's just see if it's going to run as you can see our application is running so we can go ahead now and implement dependency injection so now we're going to get dependency injection to work in asp.net core and if you remember at the beginning of the video i showed you three different service lifetimes that are available with dependency injection in asp.net core what we're going to do is we're going to set up a service for each of those service lifetimes so we've got the project open in front of us so let's go ahead and create a new folder and let's call it services so we're going to start off with a new interface i'm going to call it i singleton service okay we need to make it public what we're going to do is we're going to set a property in here of time and i will show you how that works in a bit next what we're going to do is we're going to go ahead and create a new class we're going to call that singleton service we're going to inherit the i singleton service so the interface that we just created we're going to bring in the time property make that public okay so we're now going to create a new constructor and the whole point here is we're going to set the time property to the current time that way we can actually test for when the actual instance is initialized and we can test out the different lifetime services that are available so go ahead and create the instructor and let's set the time the time now and we're going to format it in hours minutes seconds and we're going to do the seconds up to six decimal places as well so we've done that for the single turn we now need to do it for the scope and the transient as well so we're going to set up separate services for those lifetime services so let's go ahead and we'll copy them and rename this to iscope service rename that we're going to do the same with this one as well for the singleton service we're going to create one for scope service inherit the iscope service and bring in the constructor rename the file as well and finally we're going to do it for the transient service as well so let's go ahead and do exactly the same thing okay so let's do the same thing again so let's rename this to i transient service and finally we are going to rename this to transient service as well like so now the next thing we need to do is we need to register these services independently injection and importantly we also need to specify which service lifetime we're going to actually use so in order to do that we go into the startup class we've got our configure services in there so the way we can do it we call our services iservice collection instance and for singleton we call the add singleton method and we pass in not just the class but the actual interface as well let's pass in the interface and the class so the singleton service is being registered as a single turn independent in dependency injection now i'm going to do the same thing for the scoped once again we're going to specify the interface and the class finally we're going to do the same for the transient so now we've created our classes we've registered them in dependency injection we need to go ahead and test them now how are we going to do that well what we're going to do is we're going to create a new controller and do it that way we're going to add a new controller gonna create an empty one and we're gonna call it di controller we're gonna set a root up here so every time a method is called within this di controller it will go through forward slash di and that is represented by this root attribute up here we're going to use the index but before that we basically need to bring in our interfaces our dependencies our actual services into the controller now in order to do that what we do is we call the constructor and with dependency injection we can actually bring in the instances from dependency injection as a parameter in the constructor so we'll bring in the i singleton service call it singleton service but do the same for scoped as i'll well that down there for you so you can see and we'll do the same for the transient service and what we want to do up here is we want to create local variables which sit within the di controller so these instances that we're bringing in from defense injection they're going to be available as local variables within the di controller so once again we're going to make them public passing the type of i singleton service and we'll call it underscore singleton service we'll do the same as well for the scope service prepend us underscore next to it and let's do the same for transient service [Applause] so now in the constructor we're going to bring in our local variables and set them for the variables that have been declared when we pass them in as a parameter as part of dependency injection our singleton got our scope service and we've got our transient service so what we're going to do now is create a model and we will return this model to the view the model is going to specify the time property for each of these services that we've created in dependency injection so we're going to go ahead and create a new class within the models folder and we're going to call it the i model and in here we're going to set up three public strings singleton time scoped time and the transient time now that we've done that we'll go back to our controller we're going to use the index method so in here we're going to create a new instance of the di model bring in the assembly for it and now we're going to set each string property to the actual time in each of our services that we set up so for the singleton time we're going to call our singleton service instance i'm going to set the property of time to it and we're going to do exactly the same for scoped and exactly the same thing for transient and we're going to return that as a view and we're going to pass in our model instance into that i'm view get rid of the default one down there okay so if we were to run this now it won't work because we haven't set up the view so what we need to do is we need to go into our views folder we're to create a new folder we're going to call it di next we're going to go ahead and set up a new view we're going to create a new empty razor view we're going to call it index.ch cshtml i'm going to pass in our model of di model and we're just basically going to output those values and what we're going to do is we're going to compare the values see how they are represented so we've got our singleton one so we're gonna specify control a single turn and pass in the singleton time on the model i'm gonna do exactly the same thing for scoped as in scope time and exactly the same thing for transient okay that's all set up now so we're going to now go ahead and run our application and we're going to load up this controller this actual page to see what values we get brought back okay so our application is now running let's give it a refresh give it a load up so on there we've got our values of the singleton scoped and the transient let's go ahead and give it a refresh so as you can see the singleton the value has stayed the same that is because with a singleton service lifetime an instance is only created when the application is started and it will remain there until the application stops but as you can see with the scope and the transient the values actually change the scope works with a http request and is disposed of when it is responded so the values for the different requests are different and transient always creates a new instance so we inject the services into the controller what i want to do now though is inject those same services into the view to see if we're actually getting the same values back for that time property so what we're going to do now is we're going to modify the index view we're going to pass in our assembly for where our dependency injection services are hosted what we're going to do now is with a razor view you can use the inject keyword to inject services into the razor view so we're going to call that i'm going to call the i singleton service and name it as a value of singleton service and we're going to do the same thing for scope service and lastly we're going to do the same for transient now what we're going to do is we're going to output the actual time value into the view from these actual injected services to see what the difference is i'm going to do it for each of the service lifetimes do the same for scoped and finally do the same for transient okay so let's start up our application and see the different values and see what they give to us okay so our application is running so let's load up the page and see what happens so as you can see with the singleton it doesn't matter whether we inject it into a controller or into a view the value is exactly the same and you can see it's the same story with scopes as well because with scoped the controller and the view is still part the same http request so the values are going to be the same but it is a different story with transient as you can see the controller transient has an earlier time than the view transient as well and that as i say is because it's initialized every time it's injected so now i want to show you another way of implementing dependency injection into asp.net core so what we've done is we've implemented each service individually but what we can do is we can also bring in an actual collection of it and then specify each service that we require for the particular usage so i'm back in my controller now and what i can do here is i can go ahead and i can get rid of these parameters which is going to cause an error but we're going to sort that out and what i can do is i can provide pass in the iservice provider instance and this will store all the services that have been registered as part of dependency injection now we can go ahead and set the local variables for these so what we can do is we can call service provider dot get required service which we need to bring in bring that in and what we do is we pass in the actual interface as the generic method we're passing isington service and we can do the same thing for scoped as well and finally for transient now with this application we haven't got too many services that this controller relies on but if you've got a lot more services that it does this is a lot more simple way you don't have to pass each service in the constructor as a parameter if you've got say more than 10 there's going to be a lot of parameters that are going to be required for the controller and it can get quite confusing so we can go ahead and do exactly the same thing in the view as well so we can inject the iservice provider and then from there we can specify our local services as part of the view and declare the singleton service and before we do that we need to pass in our assembly so we need microsoft.extensions.dependency injection then we can call the get required service from the service provider instance and pass in our service as the generic type do the same thing for scoped service and finally for transient okay so we've made that change let's run our application and just make sure it works okay so our application is running let's load up the page again and let's just make sure it works so as you can see it's all working using the iservice provider now i want to look at some of the common errors you might face when using dependency injection in asp.net core so what i've done here is i've opened up the singleton service and what you can do is very similar with what we did with the controller is we can actually pass in dependency injection services that have been registered and we can pass them into the constructor like we did with the controller so with the singleton service i'm going to pass in the i transient service but what i'm going to do now as well is i'm going to go into the transient service and pass in the i singleton service now i'm going to go ahead and run the application to see what happens as you can see we've got an error and the error reads a circular dependency was detected for the service of type by singleton service if we come out of this if we go back into our singleton service you can see we're passing in the instance of the i transient service but if we go back to the transient service we're passing in the i singleton service so the thing's just basically going round and round and that's not allowed in asp.net core now the next thing we need to have a look at as well is if we go into our singleton service let's pass in the iscope service let's go ahead now and run that and see what happens okay so we're getting an error and the error reads cannot consume scope service round the code the i services i scoped from single turn i singleton service so when the singleton service is looking for the scope service it doesn't know which scope to use so it froze that error now if you want to use a scope service in a singleton service the best way of doing that is explicitly actually creating the scope which we'll have a look at in a bit and the final error i want to show you is if we go into startup class so if we go ahead first and we will remove that instance now if you're starting up in dependency injection it's hard to get your head around it at first and you might do a common thing like you might forget to actually register the service so we'll show you what area you get if you do that so if we remove the transient one let's see what happens so let's run our application again let's try and load the page and as you can see here it's got an error saying no service for type i transient service has been registered so that's a common area you'll get if you get to actually register the service as part of dependency injection so now i want to go ahead and explicitly define a scope in asp.net core now the best way of doing this is through a hosted service now hosted service is basically a background service and within that we're not actually having the scope defined for us so we need to go ahead and define the scope for us so what i'm going to do here is i'm going to services i'm going to create a new item i'm going to call it di hosted service what i'm going to do is i'm going to pass in the i hosted service interface and i need to bring in the reference so that's done and i'm also going to bring in the methods as well that we require now before i do anything into this what i need to do is i need to go into startup go into the configure services method call our instance of i service collection and what i need to do is i need to call the add hosted service method passing in rdi hosted service okay so back to our di hosted service we don't need to stop async so what i'm going to do that is just going to return a task dot completed task now with the di hosted service i need to call in the constructor and i need to pass in a parameter so let's call the constructor and what we're going to do is we're going to pass in the iservice provider instance and like what we did with the controller we're going to pass in a local variable for it we're going to set that up here make it public what we're going to do is we're going to set that variable to the parameter that we're passing in so now that we've got our instance of iservice provider available to our hosted model or hosted service we can go ahead and use it to create a new scope so we go in here we create we declare the scope and we're going to use the service provider dot create scope which we need to bring in the reference gone ahead and brought in microsoft.extensions.dependency injection let's now go ahead and created our scope what we can do now is we can bring in our services from dependency injection that is required for the skype in order to do that we declare local variables for them and we can use scope service provider get required service and we pass in our interface as the type you can do the same as well for scoped and exactly the same for transient service now in order to test this as a background task so what we're going to do is we're going to write each time property to the debug so we can go ahead call debug we need to bring in the reference in for that which we've done i'm going to call the right line method i'm going to use the string that format singleton time [Applause] zero and then we're gonna pass the time in the time property as a parameter exactly the same thing for the scoped and do the same thing for the transient now doing it this way means that we can have more than one scope we don't have to be limited to just that one scope so we can go ahead and do that if we go in so there we go we've got two scopes in here so the singleton service and the transient service will work in exactly the same way as it does before the singleton service lasts for the lifetime of the application and the transient service always creates a new instance regardless and with the scope service it creates a new instance for here and it remains to the end of the scope which will be there for this scope service it begins when this is actually declared and then it ends when the scope's finished let's go ahead now run our application and see if we can see those lines written to our debug now before we do that though we need to just go ahead and return a task.completed task because we were getting a compile error let's go ahead now and run that our application so we've got our debug open here and as you can see it's outputting from our hosted service the singleton time the scope time and the transient time now something to take note on this is the scope time there it's 0.995 on the end whereas with our new scope it's dot zero zero six on the end so you can see it's a new instance of the scope for each scope that we actually define so now i'm going to go ahead and show you how to use a delegate when registering a service in dependency injection now you might want to use a delica to explicitly define the instance of the service this is particular if you're not using dependency injection for one of the parameters just say you're passing in a string or an integer so in order to do that we can still use the add singleton method but there's another extension here and we've got this delicate here it requires an instance of iservice provider passed in and it needs to return a singleton service we're going to go ahead and do that we'll name the instance service provider and now we can go in here and create our method so in here would just return a new instance of the singleton service just like that so this is absolutely fine so if we wanted to create a new parameter and it's not part of dependency injection we can do it this way and that's the way we can do it explicitly so that's how you use dependency injection in asp.net core however if you use dependency injection in net framework before you might be familiar with autofac autofaq is another package for using dependency injection but whereas with asp.net cause dependency injection it's quite simple with autofact it's a bit more detailed such as being able to choose between seven different lifetimes however my personal opinion is that asp.net cause dependence injection is more than sufficient to do the job now thanks very much for watching and remember to hit a like on the video
Info
Channel: Round The Code
Views: 1,742
Rating: undefined out of 5
Keywords: DI, dependency injection, dependency injection .net, di .net, di .net core, dependency injection .net core, dependency injection asp.net, di asp.net, di asp.net core, dependency injection asp.net core, di .net 5, dependency injection .net 5, di errors, di .net errors, singleton .net, singleton asp.net core, singleton .net core, scoped .net, scoped asp.net, scoped asp.net core, transient .net, transient asp.net core, transient .net core
Id: EjFE5d2lCV4
Channel Id: undefined
Length: 31min 46sec (1906 seconds)
Published: Thu Feb 25 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.