Dependency Injection in WPF in .NET 6 Including the Factory Pattern

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
dot net core has built-in dependency injection that we use in every web project type we create however did you know that you can also use the same dependency injection in the net core version of wpf in this video we're going to enable dependency injection in wpf and then use it for some common scenarios including creating multiple forms now if you don't know me my name is tim corey and it's my goal to make learning c-sharp easier i do that by providing videos here on youtube multiple times per week plus i have a weekly podcast called dev questions i also provide courses on c-sharp web development and much more at imtimcorey.com profits from those sales are what pays for the free content here on youtube so that everyone can have a great education in c sharp not just those who can afford it in this video as with most my videos i'll create some source code if you'd like a copy of today's source code use the link in the description to get it okay let's go to visual studio and we're going to create a new project and we're going to choose a wpf project so wpf application this is a net 6 application now if you have the net framework templates installed as well make sure it does not say net framework in parentheses okay so you'll see down here wpf app.net framework don't choose that one choose choose this one hit next and we're going to call this dinwpf and we'll say di and jpf app and we'll hit next and we're going to choose a net six version so it says dot net core dot net six is actually net core just drop the core name but it's dot net sticks which is the latest version as of the time it's video but if you're on net seven or beyond you can still use that uh but it's up to you if you want to choose.net 6 or the latest version hit create and when you do we'll get a pretty typical application now we're going to do a little bit of cleanup on this because it's a little messy at first but let's first start off by just hitting run once this is done building right now it says attach wait until it actually says uh di and wpf so we need to do a build here now it's built and now it says di and apf there we go so you run this it's going to start off the model screen but there's our our wpf app not much to to show yet it's just a pretty simple app the yellow border around here and this little thing right here that's from visual studio because of the fact that we're debugging that's kind of like these are like kind of like your tools you get in a browser your f12 developer tools that's kind of the same thing we can get with our wpf apps we'll leave that minimize for now and hit close now let's go to our main our main window.cs so manual.xml.cs it's got a lot of stuff in here reason to clean up lots of usings let's get rid of them we only need the system.windows and let's put a semicolon after our namespace to make it a filescope namespace let's get rid of our useless code comment and that's where we're left with this is the the code that starts our main window so let's initialize the components that eventually becomes this page right here we're going to modify this page in a little bit but let's close both of these down for now and let's understand how a wpf actual app actually runs it does not start at mainwindow.xml instead it starts at app.xaml if we notice here startup uri is main window.xaml this is how you change it to a different window if you want a different window to be the starting point of your application now for us what we're going to do is get rid of this entry right here we're not going to have a startup that starts here in this xaml code instead we're going to go to the code behind for app.xaml which is app.xaml.cs this is where again let's clean up the use those code comments and all the using statements we don't need and make this a file scope namespace but this is the true starting point of our application there is no program.cs unfortunately really should have one i think but it doesn't so we have app.xaml.cs and that's the starting point of a wpf application so it's in here that will do our work so inside this part this public partial class app we're going to say public static i host and control dot to well we don't have even a using for this yet we're going to have to add a a new get package for that we're going to do it in just a minute app host and we'll make this a get and a private set so it's going to be a a static property which we can access anywhere so right we're going to set this up in just a minute we also get nullable meaning you can start at null but we need to have this ihost which is actually part of dependency injection and to do that we have to add two nuget packages right click on dependencies manage nuget packages browse in here we're gonna say microsoft dot extensions dot dependency injection that's one and we also need hit okay we also need microsoft extensions dot hosting right there so we need these two they're from microsoft they are um they're ex they're nuget packages that support net now you may wonder well why isn't it installed right inside of net core itself like why is this not part of net core if it's actually truly part of net core well the reason why is because they did that in dot-net framework so dot-net framework had everything inside the framework the problem was we didn't need everything all the time and so with net core they took the opposite approach where they said let's put only the stuff in net core itself that everything needs and then anything else will break apart into a new get package still supported by microsoft still a part of net core but this way you can only bring in the pieces you need and make for a more performant smaller version of net core then we have a dotnet framework where we brought everything including the kitchen sync along with us so we now have two new get packages installed microsoft.extensions.com injection and microsoft.extensions.hosting these are two that come from microsoft that support what we're trying to do so here you can hit control dot to add that using for microsoft.extension.hosting so now that we have this set up we have what's going to be our host for our application let's talk about how to configure this let's create constructor and in here we're going to do is say app host equals host dot create default builder if you're familiar with how to work with um other applications such as blazer server or asp.nbc or whatever else you'll see something like this a lot the create default builder this is what sets up things like and it has a listing here i configuration i logger and it even sets up the um the system to be ready for dependency injection so there is our default builder and then from here we can say we'll put enter key we don't put a semicolon yet we're going to continue to extend off of this we're going to say dot configure services and then we're going to say we need two things in here we need host context and the services and we're going to have our curly braces here inside our clear braces we'll have some code so let's do it at the end though dot build so what we have here is we have our default builder we've set it up it has eye configuration so we have uh apps.json we can have apps.development.json seekers.json all the rest we can have ilogger for logging your application and we can also configure our services and that's what we're doing right here our services are dependency injection now once we're done configure services we build this they don't have any services yet we'll come back to that in a minute but we're going to say now built and that's going to build this app host remember we're assigning this to app host now that we have it built we need two more things we need and i'll explain more with this as we'll come back to this uh so protected override on startup now we're gonna mark this as async so we have protected override async void on startup and what this is going to do is we're going to start up our application but before we do the base on startup we're going to await app host dot start async sorry await the start of our container now it's going to say hey that may be null here we know for effect it's not null that's the exclamation point takes care of because of the fact that we have created it in the constructor so we've created right here therefore it's never going to know once we start using it so we can say the um the character here that ignores this warning now i covered this more in my video on nulls so if you're not from that character go watch my video on nulls because that will enlighten you as to why we're doing this it's really a design time thing where we're talking about just telling the compiler hey ignore this warning is not really going to be nullable so we're going to start our our application so we built it here and put it here this is where we actually start the application and then we're going to say var startup form equals app host dot services dot get required service control dot to add that using for dependency injection and we'll say main window and then startup form dot show so what is this doing well once we start our container we still have to have an entry point to our application and the way wpf applications work that's kind of the same way that winform applications work is that the starting point is your first form and that form closes down the application closes down so we need to start the first form and that's this right here we get that form from dependency injection and we show it and then we're good to go we also need one more override so protected override on exit so in the application exits we're first let's make this async we're going to first await app host which we know for fact is not null dot stop async so when we exit the application we'll stop the the app host and then we'll do the rest of the exit things we need to do so we have now configured our wpf application to handle dependency injection now we haven't put it in dependency injection we can do that right here services dot add singleton and main window and yes i said singleton because we don't create more than one instance of our main window um there may be reasons why you'd want to create more i want i can't think of any because your main window is that that window again that when it closes the whole application closes so you typically don't want to create multiple of those and create confusion typically you want to create sub windows or or child windows something else like that that might have multiple but for the main window singleton is usually the right call for our application so we've add that one service which we're requesting right here and if we were to run this remember i took out that entry for the startup uri if we run this we still get our application launching so it still runs but now it's launching with dependency injection and we can prove that this works with depends injection let's uh start closing out of the things we don't need um well that's really just nothing actually so let's let's create let's do a class library just show that you could use a class library so right click on solution and say add this is still a sample kind of thing it's not a there's class library it's not a a real project we're just doing sample stuff here but let's let's create a um our wpf uh library and yes.net six hit create and we're going to delete class 1 and instead we're going to right click and say add class and we'll call this data access and we'll get rid of all the using statements we don't need we'll make this a file scope namespace and make it public and we're going to create a public public string and we'll call this git data so this method gets data right and it's going to return this is the data from the data access class okay obviously that's just sample it's not actually going to sql and all the rest but that's the stand in for what you would have for a data access class and a method now let's do a control dot to create and extract our interface into a new file there we go so now we have something to put in our dependency injection so let's right click on dependencies and say add project reference select the library hit ok and now we can compare our using statements and say using wpf library and then down here we can say services dot add transient i data access and data access like so just like you would with a a web application we just add our services in the the services area and then we can request them so in our main window.xaml.cs we have a constructor which by the way um yeah we've cleaned this up mostly let's clean up the rest of it let's um ask for a i data access control dot to add a using and we'll say data access and we can say control dot to create an assignment field and now let's go to our main window.xaml and we're going to do some really quick and dirty stuff here um let's let's first of all trim this down to a more usable size let's do i don't know let's do 300 by 500. i'm going to put a a stack panel here and the orientation is vertical and let's do the horizontal alignment as center and vertical alignment is uh center let's do a stack panel and now put it right in the middle of form again really quick and dirty but we're going to create a button here and we're going to say that the x name button is [Music] get data we get data that's fine and we will say get data of course that button is really tiny so let's say that the let's change the font size overall for application so up here we can say font size equals 22 24 yeah 24 and we'll say that the margin is actually padding right padding is 20. there we go just something um 2010 there we go better so we got a button it looks like that it says git data and then what we'll have is we'll have above this we'll have a text block that has a name of data and that's it yeah that's it it's going to sit above the button and it's going to have this um the name of data so in our code behind let's actually double click on our button which creates the event and we can say uh data dot text that's our text field equals our text block equals data access get data all right that's it let's let's run this make sure it runs it seems to there we go get data click it this is the data from the get data or get from the data access class boom done so we've got data from our our data access class using dependency injection so in our our main window we have said give me an id to access and then used it so that's dependency injection we've just requested it and it's just happening because the fact that our we create our main window it says i depend on i data access which is okay there's the implementation pass that into main window when you construct it now you that's just basic data access or beta basic dependency injection in wpf we're done we're working that's all you really need to set up dependency injection well almost all you need because there is one more thing to think through and that is how do you register your forms because maybe you have another button let's create another button here let's create let's copy this and we'll take off the on click and we're going to change this from get data to open child form how about that and we'll say open child form like so and we want this button to open a new form which we don't have yet so let's right click on the project and say add and we'll say new item and we're going to say a a window wpf window you can also do page or use control we're gonna do window and we're gonna say child form is the name there's our child form and if we come down here let's make this um let's make it smaller let's go with maybe 200 by 500 somewhat that and then we're going to create our stack panel down here so we have it and orientation is vertical and let's have a a text block here that has let's create our font size up here of 24. textblock is create this is the let's call the child form just have something there let's also make this the horizontal alignment equal center there we go so it says child form that's all that's all it does but we want to open this child form and maybe more than once so how do we do that because we could put it in our dependency injection like we have main window where we say services dot add transient and say child form but how do we get more than one form to open so if we go over to our our main window dot xaml and double click on this open child form if we were to ask for a i or for a child form control dot to create a sentence field we could say child form dot show but that's only going to open one form so he run this right now it's going to open our screen and actually the form is two but open child form and that open a child form i click again nothing seems to happen i keep clicking it nothing seems to happen it only opens the one form but what if i wanted to have multiple forms opening up well i can't do it this way so if you watched my video on the factory pattern that's been very very helpful here so let's create a abstract factory so let's let's do this inside of a form or a folder so let's add a folder we're going to call it um startup helpers and inside here we're going to add a class and we'll call it abstractfactory and we'll put our semicolon here and get rid of our usings and make this public and in our abstract factory we actually want to be of type t wants to be a generic factory we want to say constructor and inside of here we're going to ask for a func of type t that is factory and we're going to do control dot uh we'll actually use system first and then we do a control dot to create a setup field for factoring so now we have this this func of type t and we're going to create the public t create method where we say return factory and we execute that function so or execute that delegate so if you if this confuses you and yes this is confusing stuff watch the previous video or a video i did recently on the factory pattern this is this is such a generic factory it's all it's doing it's creating a generic factory which is going to generate for us our our forms for us okay so now we have our generic factory we can do is we can create another let's create our class in here and let's call this class service extensions again get rid of the using statements and yes put your semicolon here and make this a public static class service extensions so we're going to do some extension methods here and the extension method right now is public static void add form factory and we're just going to ask for the implementation or just t form and say this i service collection ctrl dot to add the using for the dependency injection services let me ignore that error so what this is going to do is create for us a a factory that will generate our forms now i did not ask for an interface and an implementation like i did in the factory video because in this case i just want the implementation we don't typically create our forms with interfaces we could you absolutely could and you could still follow the same pattern of interface and implementation but in this case we're just going to do the implementation i am going to put a where clause here where t form is a class so let's just limit it to a specific class and then we're going to say services dot add transient the form so you add the form of the transient services dot add singleton a func of the t form and then we're going to create that x arrow open close parentheses arrow x dot get service of t form open close our parentheses our semicolon at the end and this is going to yell at us oh function yellow is first for using system and this will yell at us because it says hey this could be null but we know it's not so we're going to use the exclamation point to say nope compiler that's not going to null because we just put that into dependency injection we know it's not going to know and then we want to add our factory which are factory we just created the abstract factory so services dot add singleton i abstract factory control dot to add that using uh oh no because i didn't create i abstract factory let's do that ctrl dot to extract the interface now we have i abstract factory so i abstract factory of type t form and then i have one too many closing right now abstract factory of type t form open close and semicolon let's put us opens up a little bit so you can move a little bit so you can see the whole thing so i've added three things to dependency injection i add my form which is a generic whichever form we give it i've added a func of that form which is a delegate that's going to create that form whenever we run the delegate so a delegate gets added to dependency injection not just the form so this is a delegate of the form which means that this will get run whenever we run the delegate and then we have our factory our abstract factory which the abstract factory will run that delegate right here on create so with all of that in place then we can come back to our uh app.xaml.cs right there and we can save all this we can add a using up here using our d i in wpf dot startup helpers makes it easier because then we can say instead of adding child form here let's get rid of this we're going to say services dot and the um we called it add form factory so add form factory for child form which what this does is it's going to add child form as a transient it's going to add a funk of child form that will run the child form or get the child form and that's going to add an i abstract factory of type child form to give us a child form with all that being said we no longer in here ask for a child form instead we ask for is we ask for and let's change this now we ask for a an i abstract factory control dot to add the using of type child form we'll call it factory let's get rid of the child form here and the child form here and we'll do a ctrl dot to create assign that field factory now down here what we can do is we can say factory dot create and immediately show that now you could put a variable and then do dot show but this will work just fine let's run this go over here first of all get data still works open child form that open the child form open child form again they open another child form open child again it opens a third child form these are all working with dependency injection so they can have their own access to data access in fact let's do that let's close all this down stop stop stop now you have to close all the forms right now because if a different form is open it still keeps everything open but once you close the last form is when it closes down so now let's get into child form and wow let's clean up child form let's get rid of our useless comments there we'll make it file scope namespace we'll get rid of almost all of our using statements just using.windows system.windows and in here we're going to ask for our i'm not even sure what we called it again it was i did access let's just grab the same let's copy this so we ask for id access and control dot to create a setup field notice i had a using statement up here for using wpf library so we've now got data access and you know we can actually just um we have our child form here we have a text block that says child form let's create another text block underneath it and give it no text where i give it a name of data access info and then we can say data access info dot text equals data access dot get data so right when it launches we'll get the data and we can run this and now we have our get data and that gets data we open the child form and it says this is data from data access class so not only can we open multiple of these forms not only can we we can get our dependency injections the main form we can also use dependency injection in these child forms to get their own instances of data access so this is how you set up data access wpf this is how you work with multiple forms if you need to generate multiple forms you know from a button or something like that where it's not from just the constructor this is how you set up dependency injection in wpf with the net core version not net framework version the.net core version so if you have any questions let me know if you need the source code for this again there's a link in the description let me know if you have any thoughts this was a suggestion from a suggestion site so if you have a suggestion go to suggestions.iamtimcory.com enter your suggestion and hopefully you'll see that in a future episode here on youtube thanks for watching and as always i am tim corey [Music] [Applause] you
Info
Channel: IAmTimCorey
Views: 40,891
Rating: undefined out of 5
Keywords: .net, C#, Visual Studio, code, programming, tutorial, training, how to, tim corey, C# course, C# training, C# tutorial, .net core, vs2022, .net 6, wpf, wpf core
Id: dLR_D2IJE1M
Channel Id: undefined
Length: 36min 2sec (2162 seconds)
Published: Mon Jul 18 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.