Dear Mr. Corey, I have to thank you a lot, for this exceptionally good explanation for DI in WPF. I just wanted to let you know, that all your free work here on YT is very much appreciated.
This was great. I have used dependency injection in WPF for a while, but still learned a lot. I got a much better understanding of what is happening; it is now something I own in my mind and not something that I can just copy and hope it works. Also, the Abstract Factory was new to me. I will definitely use it. Thanks.
Tim, I had worked out 85% of this already but to show it with the abstract factory pattern is just brilliant, it is just amazes me why you give this stuff away for free. Now all I have to do is find a customer who wasn't to go to core before I rentier.
Hey Tim! After reading about 99lbs of Books and watching about 1k years of youtube - Videos, now I finally understood it. Watching your videos is never wasting of timel Thanks a lot
Thank you Tim! I've been working in .NET 6 Web API and the dependency injection is SO easy it's effortless. This is a little different, but I get it now.
Hi Tim, I really enjoyed this video! I appreciate the way you dive deep into topics and prioritize doing things the right way, even when shortcuts are available. For instance, your approach of creating an Interface for the library class stood out to me. I understand that for beginners, these finer points might seem puzzling, but once the underlying concept is clear, they'll surely be grateful for your thorough approach - just like me. Your expertise shines through your videos, often without you even realizing it. Even details like setting the form's width to 500 show your experience at play; you intuitively know that text won't fit well in anything smaller. Your videos are of exceptional quality, and I'm a devoted fan from Houston, TX. Keep up the fantastic work!
This is useful also to us who have been dealing with DI for a long time. I'm not working on anything using WPF right now but showing how to wire up a custom Host is useful. I have not created any Abstract Factories myself, but it might be useful. Accessing IServiceProvider is not so pretty.
This is super stuff. My suggestion/request --> Add MVVM Or as how James Montemagno would call it --> MVVMS (Model View ViewModel Services) --> Give credit where credit is due ;) I would call it MVVML (Model View ViewModel Logic), because with dependency injection you can put pretty much anything in there, as you just proved. By the way, James used Maui to show this, which has the dependency injection already present in the template. Again, as always, great stuff Tim
Your video is perfect!! I do a similar thing for Winforms using DI with NET 6.0. For the extension method I would return an IServiceCollection to allow the chaining of Add* commands.
CTRL + R + G => Removes unnecessary usings :) Not sure if you are aware of this hotkey, just sharing it with you in case you're not. Nice vid, thanks for sharing!
The abstract factory is great. I also setup my extension to auto-attach the viewmodel for the new window as well. example: services.AddWindowFactory(); then I have 2 generic types on the factory extension method. When adding a singleton for the delegate, I instantiate the window and the viewmodel and set the window.datacontext = the viewmodel and return the window.
Hey thanks! I was using this wacky way of doing DI before I saw this. Basically I was instantiating a new ServiceCollection within the main window Cs file and then adding it to the Resources after building the service provider (serviceCollection . Build service provider). The downside with this approach was I couldn't get EF Core migration to work (was complaining about extension hosting missing). So everytime I had to switch over to the Blazor project add my migration then set the WPF app as startup again. But it all make sense now; I needed that nuget package. But I do like the way u add it to app; alot easier.
Intetesting topic! Could you have injected the service provider and just asked that for a new instance in the click event handler? Also, managing resources with DI in scoped and keyed services in WPF is interesting. For example in F# it doesn’t seem possible to use specific window classes but using keyed services we can still discriminate between different windows (when specified in XAML).
Tim Corey, once again you amazed us!! Congratulations for your excellent tutorials!! Thanks a million!! I have a question though that could help a lot of us. My question is: how could we work around the DI part when our app is using community mvvm toolkit. For you this is a piece of cake to add 2-3 minutes to extend your video teaching us how to handle views and viewmodels and how to inject them and where. Thanks again for your excellent tutorials!!
Thank you Tim that's very helpful! Any chance you could build on this example adding CommunityToolkit.MVVM and databinding to view models (with both MainWindow and child forms)?
Hi Tim! Thanks for your amazing content. Something ive been struggling with in WPF is getting environmentspecific appettingsfiles to work. That is a .Development.json, MACHINENAME.json etc. A little video on this would be great. Thabk you
Microsoft Genric Host, Depenedancy Injection, Configuration, Logging ..etc is the best thing to happen to .NET, it just blows any other language out of the park in this
Great video. Between this and your ASP .NET Core DI video, I'm finally starting to wrap my head around .NET dependency injection. 8:02 Is there any reason not to configure and build the AppHost in the static constructor? Or even directly assign to the property? Or perhaps use a readonly static field?
With static means it's available from the start of the program. You can think of it as a global variable (since it's public) available from anywhere while the program executes.
I love this video! I also am loving my Pay For Blazor Class! I am currently taking this in to the real world with the next challenge this video does not address. Unit Testing with NSubstitute/Moq the Abstract Factory Pattern. - It is more difficult that just Substituting for the Abstract Factory Pattern. We also need to Mock the Other Dependencies TForm and the Func. I only got as far as Mocking the Abstract Factory Pattern. Not sure how to Mock the others....Another video? Some custom consulting? Do you do Custom Consulting?
Great Video! Question: If I inject the view into the viewmodel abstractly (as IMyView) does it still violate the MVVM rule about the ViewModel not having any knowledge about the view?
Hi Tim, great video as always. I note that for the windows (like MainWindow) you add the implementation directly to DI, elsewhere I have seen code that has an interface to the view and then registers e.g. IMainWindow, MainWindow - like registering other dependencies. I don't see the point of creating an interface to the window, much like you show here. Is there any reason to? Similarly if using view models, would you create an interface to the view model? I can potentially see more use in that, but as view models are pretty tightly coupled to the view anyway and typically that's the main / only place to inject them, is it worth it?
33:00 Eventhough this is just a sample app. It would be good to have some sort of counter or list of open windows so if you kill the MainWindow, the childforms will close as well so you don't need to close them seperately.
Add each window/form into a collection when they're created. override OnClosing in MainWindow and iterate each window in the collection and call Close().
Hi tim, thanks for another great video. I wanted to ask i have been using IServiceProvider, ServiceCollection and BuildServiceProvider Method till now for DI in wpf. Should i switch to using IHost now? what would be the difference.
Great Cideo, As Always! I would love to see a video on using this in a WinUI 3 Desktop App. I was able to launch MainWindow as a service using OnLaunched instead of OnStartup and Activate instead of Show. Microsoft loves renaming everything for no reason. Unfortinatly, I was not able to find a Windows SDK App equivilent for OnExit :(
Hi its Nice video explainig the DI Concept, May i know how to create view by closing the previous view and create new view like menu clicking to load new view
Another awesome video. thanks, Tim. but I have a question. Is it relevant to use Dotnet dependency injection with Caliburn micro instead of Caliburn micro's dependency injection?
hi Tim great video. Got to the end and you said its NOT! for .net framework, but for Core? Im doing .net framework because this app will hopefully be able to use older code? I want a Main form and then Child forms where its only 1 allowed (singleton) if possible. Will this example work in .net framework? Also I have never used the Factorial arg in c# before variable name becomes VARIABLE_NAME!!! thats so interesting. Im a dinosaur from punched cards and functional programming
Yes, I was trying to be clear that I was using .NET Core (now just .NET) in the demo rather than .NET Framework. Things will be different in .NET Framework. You would need to use a third-party dependency injection library like Autofac, since DI is not built into .NET Framework.
@@IAmTimCorey you said that its core not .net framework. I needed to switch to classic old winforms that i used for years and can get things done, here with wpf it seems so fragile and limited choice of items to put in the designer. I started with the microsoft DI and it failed at the spot of using ? or ! that in 7.1 isnt there, use version 8.0? you cant. Not sure if DI is needed the only idea was to bring in outside code of unknown type or version. I went from doing forms, to embedded cpp to web and now forgot things, I hope to have many panels depending on what its doing, a Tab control could work where each one is its own blank canvas? Trying to drop 5 panels on top of each other hoping to bring back the way its done? if there are 5 or 6 buttons on the left each opens its own majority of the page with its own buttons, text input etc, if wpf can do that better great. I did your example here maybe 5 times hoping to grasp it and its very well done and makes sense. repeating the task a few times helps to memorize it.
@IAmTimCorey Thanks alot, i wish to see more design patterns in wpf, especially modern .net 6+ I want to use mediator pattern in wpf and have multiple threatds handling multiple things, so message passing between the components are done in the mediator
So the factory is for when you want a new instance every time you ask for it. (I thought 'Transient' already did that). But most of the time you would want the same instance, if you are keeping track of state, navigation manager, etc. Or am I wrong?
A factory can accomplish different tasks based upon its design. For instance, the HttpClientFactory will handle the lifetime of HttpClients internally so that they are properly recycled and reused in order to not exhaust the sockets on a computer. Another factory might create a new instance when requested, which is different than creating a new instance when the class is constructed.
Thanks for the great video, this helped me create Console Apps with DI, but what is the difference between Apphost.RunAsync() and StartAsync(), seems like the task from RunAsync is not returning !
Hi. I have a question about the IHost object. You make it nullable, but then you use the ! to override the compiler warning. You stated when you created it, that it needs to be nullable. Can you explain why?
Allow me to answer. It is nullable to avoid the warning. Nullable reference types check whether fields and properties are assigned in the constructor when the members are not marked as nullable. Tim chose to init the host in the lifecycle event so to avoid the not initialized warning he used the bang (!) symbol when accessing the nullable Host property. You could new up the Host in the constructor of App class and assign the property there. Then you would not have to make it nullable. But putting logic in constructors are not advisable. I’m not sure why Host is static. Though. By default, the templates are not set up aa enforcing nullable reference type checks as errors. So all you get now are warnings.
@@marna_li It's just moving the warning from one, focused place to every usage of the property which essentially cannot or should not logically be null. The usage of NRTs is incredibly silly at times in this video.
@@marna_li Host is static so as to be accessible from the entire application, e.g. to access GetRequiredServices. As for new-ing up the host in the constructor, that's precisely what Tim is doing. Unless you mean new-ing up in the static constructor?
As always, thanks for the great content, Usually in a main window, the need arises to call many child forms, for example: a form for sale another for financial transactions, another for some reports...etc this could mount to tens of child forms for a complex business application, adding a parameter for each type of child forms in the main window constructor feels very wrong, is there another way to help in that scenario?
I’ve seen it done with an collection of generic viewmodels in an AppViewmodel type container. When a new form is required, the viewmodel for that form is created and added to the list, the UI then opens a generic form and using templates, displays the correct layout for that viewmodel. It’s not going to save code over what Tim has done, but it encapsulates the form logic into the viewmodel that owns the form.
very nice video, very helpful. would you do a basic tutorial on di in a blazor-hybrid-wpf project? in the microsoft docs tutorial they use services = new ServiceCollection() and Resources.Add("Services", services.BuildServiceProvider()); i followed your code sample to understand the differences, but it seems to me that the one created in app.xml has no relation to the "ServiceCollection" as created by MS example. i'm confused and would love to see a video explaining this. cheers
Very useful video Tim. I am new to WPF and .Net and I am dealing with something like this. But I am stuck because I am passing the environment variable and want to call the WCF service binding uri for that passed environment variable. Is this achievable using this? It looks to me like I have to first add the service binding for all the environment before I can call it? Or am I doing something totally wrong? It looks redundant to me to add the same service just to get it working for all environments. For Example if I pass the environment variable user input as Dev1 then I want the to do something by calling the Dev 1 service to be called. If I pass dev2 then dev2 Uri to be called. QA then qa uri and so on.. Basically developing an exe application in WPF with .Net framework and they want me to pass the environment variable. Please advise. Thanks
tks very much, Please if we have for example ChiledForm that accept a IDataAccess as a parameter, how can I open it from another form without using Factory, I don’t want to pass a IDataAccess as a parameter when I call ChildForm.Show();
@@IAmTimCorey the MainWindow is the parent form, i use Repository pattern, i pass the IRepo as a parameter, when i pass it to the constructor of MainWindow this gives me error: system.invalidoperationexception: 'unable to resolve service for type 'dataaccess.dbcontext' while attempting to activate 'dataaccess.repositories.genericrepository`1[repo.models.user]'.' then i create a variable for IRepo with new keyword and i pass it to childForm to open it, but if i do i must to pass a dbContext to create the IRepo variable: IGenericRepository repo = new GenericRepository(new DataAccess.DataContext()); i don't want call or Pass DbContext in my frontend. tks
What if you need parameters for the factory.Create() function? I usually use parameters like fullscreen = true, size, center = true/false etc when creating windows using a helper function (and different parameters for different types of pre-defined utility windows -> e.g. a "form popup window (gets an UserControl as a parameter)" will be displayed without minimize/maximize box and a "fullscreen image displayer" (gets a byte[] or an Image as a parameter) will be displayed without borders and without title and buttoms) Is the solution creating a different IAbstractFactory for every of these types of windows? (one for no params, one for a "usercontrol form displayer", one for "image displayer") and thus getting 3 IAbstractFactory types with each one prescribing different params in the .Create() function?
I don't know if this might help, but Dependency Injection works best with what is called Parameter objects, where you pass your parameters as Object and you define your classes as generics, this also helps you when have multiple implementations or decorators .
I showed how to do that in the previous video. I put the time marker at the time when we actually send parameters, so you can see how it can be done: ruclips.net/video/2PXAfSfvRKY/видео.html
Hi Tim, do you have any course for non us people, I've seen on your site but after converting to us dollars it became too expensive. Can you make some cheaper modules?
The paid content is used to fund the free content. That's why we keep it at the price we do. Lowering the price to accommodate more cultures and economies would actually reduce our capacity to make more free content. However, because of the pricing being where it is, we have been able to give away three full courses here on RUclips (TimCo Retail Manager, Tournament Tracker, and Suggestion App). We have over 11 days worth of videos here on the channel and more is being added every week.
You can set the data context in xaml, but that will only give you an empty view model, it won't have anything populated. You can't put data into it through xaml. Reference your data context here That's the only way I know in xaml to get a VM going, everything else involves varying levels of C#
The dataAccessInfo is the TextBlock on WPF form. That is what I named it. So, it has a bunch of properties for that TextBlock, including the Text property. That's the property we used to put text on the form.
Totally lost on this one Tim. I not in the world of WPF so this is not helping. I have a Services Project that calls a Class Project method that then needs to call a EF Core using Repository and Interface. As a Blazor project, this all works out of the box with a simple @inject. Why so hard to get this to work in a Services Project. Do you have a video that shows close to this type of project setup. Services Project, calling a Class Project that calls Repository\Interface Project to do the EF things?
It sounds like you just need to get dependency injection set up in your project. Then you just ask for what you need and get it. It should be no different than Blazor at that point.
One would think Tim but it's seem not that easy. I trying Autofac to see I could in this. In a Blazor project I simple Add @inject IUsersRepository _userRepository And then I can call everthing. In a Services Project, no. Here what I have in the Services project but if I try to call a method in a IWhateEver, it a no go public static void Main(string[] args) { var builder = new ConfigurationBuilder() .AddJsonFile($"appsettings.json", true, true); BuildConfig(builder); var config = builder.Build(); var dbWaterConsentsCoreConnection = config["ConnectionStrings:WaterConsentsCoreConnectionString"]; IHost host = Host.CreateDefaultBuilder(args) .ConfigureServices(services => { services.AddHostedService(); services.AddDbContext(options => options.UseSqlServer(dbWaterConsentsCoreConnection)); services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); services.AddTransient(); services.AddTransient(); services.AddTransient(); }) .Build(); //And my go at using Autofac. var builderAutofac = new ContainerBuilder(); builderAutofac.RegisterModule(); builderAutofac.RegisterModule(); builderAutofac.RegisterType(); builderAutofac.RegisterModule(); builderAutofac.RegisterType() .As() .SingleInstance(); builderAutofac.RegisterType() .WithParameter("options", DbContextOptionsFactory.Get(dbWaterConsentsCoreConnection)) .InstancePerLifetimeScope(); IOTDevicesRepository whyDontyouwork = new(); whyDontyouwork.Get(1); var container = builderAutofac.Build(); var studentRepository = container.Resolve(); studentRepository.Print(oStudent); //This will not work. var iotRepository = container.Resolve(); var pleasework = iotRepository.Get(1); host.Run(); }
It gives us the keywords for accessing things more easily from Appsettings. It is an interfaces and abstractions library that other libraries build off of, so we can use it to get access to those same abstractions.
@@IAmTimCoreyI have another question if you can answer it. I have a list in WPF, and each item in the list has specific commands associated with it. When I click on a particular item, I want to change something on the view model. Each of my items depends on the view model, as well as on some other information. How can I correctly instantiate these items for my list? I cannot use a factory because it's not just the view model that I depend on; I also need to include additional information such as name, ID, quantity, etc.
Absolutely. The key is that a lot of desktop apps are really old (so they are still WinForms). For newer apps (made in the last 10-15 years), WPF has been a solid choice so a lot of companies have chosen it.
The same way you get the first child form. You specify what each form depends on in the constructor. When DI goes to satisfy the main form, it will see that it needs a child form. When it goes to provide the child form, it will see that the child form depends on a child form of its own. It will get the grandchild form first and work its way up the chain.
No, the desktop app is still alive and well. They just aren’t used as much for sample projects. When you look at what businesses build (the people employing developers), there are still a ton that use desktop apps. They are the right choice in a lot of situations.
The reason it is called that (and this isn't C#-specific) is because we are injecting our resolved instances into classes when they state they have a dependency. So instead of a class having the line "var log = new Serilog()" in it somewhere, the class asks for a logger. The difference is that in the first way, the class forces the application to take on the Serilog dependency. In the second way, the class asks for some type of logger. It depends on a logger, but it doesn't care which one. Just one that satisfies the interface. So, when the application runs, the dependency injection system can figure out which logger to create and then it injects that instance into the class that requests it.
Hi Tim, I tried what you show but have encountered an issue. In my App.xaml, I have a Style defined in my ResourceDictionary with x:Key="GeneralButton". Over in my MainView.xaml, I bind to this style like so: Style="{StaticResource ResourceKey=GeneralButton}". However, in my MainView.xaml.cs, I run into an error when executing the InitializeComponent() line: "'System.Windows.Markup.XamlParseException... 'System.Windows.StaticResourceExtensions' threw an exceptioon... Exception: Cannot find resource named 'GeneralButton'. Resource names are case sensitive". My understanding is that before I was subscribed to the Application_Startup event: , which seems to have included an initialization of the ResourceDictionary in my App.xaml. When I override OnStartup, however, this seems to not take effect. I was wondering if you know how to keep my ResourceDictionary where it is, as well as overriding OnStartup. This approach seems more elegant to me than resubscribing to the Application_OnStartup event or putting my Style definition in MainView.xaml (I want it to be defined at the application level). Great video by the way - been learning a lot from you! I love dependency injection.
@@IAmTimCorey Haha, I see. In my option you should overall limit the use of the bang operator to minimum. Don't know how experienced you are with Typescript but it's not uncommon to see it outright banned in some scenarios in many typescript projects. It's part of the reason why cases like this immediately pop a "warning" in my head as I see it more like a hack around pretty much an unsolvable problem of compiler not always knowing what logically is or is not possible, rather than something you should sprinkle around in your code. Just my 2 cents 🙂
I tried creating something similar with my own DataAccess class, nothing special to it. I register it as a transient services.AddTransient(); Later in a different class I try to get the service by calling AppHost.services.GetRequiredService(); but this throws an error: "No service for DataAccess has been registered". Does anyone have an idea of what could be causing this issue?
Very important video ... most people know perfectly how to use DI in ASP.NET but have no idea how it is done in other projects
Thanks!
Dear Mr. Corey, I have to thank you a lot, for this exceptionally good explanation for DI in WPF. I just wanted to let you know, that all your free work here on YT is very much appreciated.
You are very welcome.
This was great. I have used dependency injection in WPF for a while, but still learned a lot. I got a much better understanding of what is happening; it is now something I own in my mind and not something that I can just copy and hope it works. Also, the Abstract Factory was new to me. I will definitely use it. Thanks.
I am glad it was so helpful.
Tim, I had worked out 85% of this already but to show it with the abstract factory pattern is just brilliant, it is just amazes me why you give this stuff away for free. Now all I have to do is find a customer who wasn't to go to core before I rentier.
I am glad it was so helpful.
I'm working on a WPF app right now, Tim, and this was a JIT video that gave me knowledge that is so handy for what I'm working on! Thank you so much!
You are welcome.
Hey Tim! After reading about 99lbs of Books and watching about 1k years of youtube - Videos, now I finally understood it. Watching your videos is never wasting of timel Thanks a lot
Excellent!
All your videos are true gems. Thanks for this tutorial!
Thank you!
Thank you Tim! I've been working in .NET 6 Web API and the dependency injection is SO easy it's effortless. This is a little different, but I get it now.
You are welcome.
Hi Tim, I really enjoyed this video! I appreciate the way you dive deep into topics and prioritize doing things the right way, even when shortcuts are available. For instance, your approach of creating an Interface for the library class stood out to me. I understand that for beginners, these finer points might seem puzzling, but once the underlying concept is clear, they'll surely be grateful for your thorough approach - just like me. Your expertise shines through your videos, often without you even realizing it. Even details like setting the form's width to 500 show your experience at play; you intuitively know that text won't fit well in anything smaller. Your videos are of exceptional quality, and I'm a devoted fan from Houston, TX. Keep up the fantastic work!
I appreciate the kind words. I'm glad you find my content helpful.
This is useful also to us who have been dealing with DI for a long time.
I'm not working on anything using WPF right now but showing how to wire up a custom Host is useful. I have not created any Abstract Factories myself, but it might be useful. Accessing IServiceProvider is not so pretty.
I'm glad yo ufound it valuable.
This is super stuff.
My suggestion/request --> Add MVVM
Or as how James Montemagno would call it --> MVVMS (Model View ViewModel Services) --> Give credit where credit is due ;)
I would call it MVVML (Model View ViewModel Logic), because with dependency injection you can put pretty much anything in there, as you just proved.
By the way, James used Maui to show this, which has the dependency injection already present in the template.
Again, as always, great stuff Tim
Thanks for the suggestion. Please add it to the list on the suggestion site so others can vote on it as well: suggestions.iamtimcorey.com/
Perfect! was watching your older videos on Dependency Injection with a view to using it in WPF 👍
Great!
Your video is perfect!! I do a similar thing for Winforms using DI with NET 6.0.
For the extension method I would return an IServiceCollection to allow the chaining of Add* commands.
Thank you! And that is a good option.
CTRL + R + G => Removes unnecessary usings :) Not sure if you are aware of this hotkey, just sharing it with you in case you're not. Nice vid, thanks for sharing!
Thanks for the tip!
The abstract factory is great. I also setup my extension to auto-attach the viewmodel for the new window as well.
example: services.AddWindowFactory();
then I have 2 generic types on the factory extension method. When adding a singleton for the delegate, I instantiate the window and the viewmodel and set the window.datacontext = the viewmodel and return the window.
How did you do it? I can't wrap my mind around it.
Awesome, Thanks Tim! I had something similar in mind for my prod app but this simplifies things even more.
I am glad it was helpful.
its very useful,i need learn the video more times。Dependency Injection always needed
Thanks!
Thank you for this very usefull video. I was searching for wpf dependency injection for long time.
You are welcome.
This is brilliant, Sir! Got to learn DI in another way. Thank you! 👏
You are welcome.
He went SugestionPattern at the end. Great video!
Thanks!
Waow!! just amazing video.
I’m glad you enjoyed it.
Hey thanks! I was using this wacky way of doing DI before I saw this. Basically I was instantiating a new ServiceCollection within the main window Cs file and then adding it to the Resources after building the service provider (serviceCollection . Build service provider).
The downside with this approach was I couldn't get EF Core migration to work (was complaining about extension hosting missing). So everytime I had to switch over to the Blazor project add my migration then set the WPF app as startup again. But it all make sense now; I needed that nuget package. But I do like the way u add it to app; alot easier.
I am glad it was so helpful.
Intetesting topic! Could you have injected the service provider and just asked that for a new instance in the click event handler?
Also, managing resources with DI in scoped and keyed services in WPF is interesting. For example in F# it doesn’t seem possible to use specific window classes but using keyed services we can still discriminate between different windows (when specified in XAML).
Tim Corey, once again you amazed us!! Congratulations for your excellent tutorials!! Thanks a million!!
I have a question though that could help a lot of us. My question is: how could we work around the DI part when our app is using community mvvm toolkit. For you this is a piece of cake to add 2-3 minutes to extend your video teaching us how to handle views and viewmodels and how to inject them and where. Thanks again for your excellent tutorials!!
Thanks for the suggestion. Please add it to the list on the suggestion site so others can vote on it as well: suggestions.iamtimcorey.com/
👍👍👍👍👏👏👏👏👏👏👏 finally the official arrival #awesome
I'm glad you enjoyed it.
Thanks, this was very helpful
You are welcome.
Thanks, I'm able to use Autofac for DI now
You are welcome.
Thank you, this was very helpful.
You are welcome.
Thank you Tim that's very helpful! Any chance you could build on this example adding CommunityToolkit.MVVM and databinding to view models (with both MainWindow and child forms)?
Thanks for the suggestion. Please add it to the list on the suggestion site so others can vote on it as well: suggestions.iamtimcorey.com/
Very useful - thank you.
You are welcome.
Hi Tim! Thanks for your amazing content. Something ive been struggling with in WPF is getting environmentspecific appettingsfiles to work. That is a .Development.json, MACHINENAME.json etc. A little video on this would be great. Thabk you
Thanks for the suggestion. Please add it to the list on the suggestion site so others can vote on it as well: suggestions.iamtimcorey.com/
Microsoft Genric Host, Depenedancy Injection, Configuration, Logging ..etc is the best thing to happen to .NET, it just blows any other language out of the park in this
They are pretty awesome!
very helpfull and interesting. as allways... thank you
You are welcome.
Great video. Between this and your ASP .NET Core DI video, I'm finally starting to wrap my head around .NET dependency injection.
8:02 Is there any reason not to configure and build the AppHost in the static constructor? Or even directly assign to the property?
Or perhaps use a readonly static field?
Hi Tim! The content is really great, but i have a question. Why the AppHost property at 7:43 is a static property and not a non-static property?
up
Because then the entire application can access the container without needing to instantiate it.
With static means it's available from the start of the program. You can think of it as a global variable (since it's public) available from anywhere while the program executes.
Great tutorial ... u r the best ❤️
Thank you!
@@IAmTimCorey I hope to make video explain the best architecture to make desktop app using (Di - Factory Pattern - UnitOfWork)
I love this video! I also am loving my Pay For Blazor Class! I am currently taking this in to the real world with the next challenge this video does not address. Unit Testing with NSubstitute/Moq the Abstract Factory Pattern. - It is more difficult that just Substituting for the Abstract Factory Pattern. We also need to Mock the Other Dependencies TForm and the Func. I only got as far as Mocking the Abstract Factory Pattern. Not sure how to Mock the others....Another video? Some custom consulting? Do you do Custom Consulting?
Hi Tim, Tanks.
What is best technology for develop commercial desktop app in 2023?
Is MAUI useable for commercial purpose ?
Great Video!
Thanks!
Great Video!
Question: If I inject the view into the viewmodel abstractly (as IMyView) does it still violate the MVVM rule about the ViewModel not having any knowledge about the view?
Hi Tim, great video as always. I note that for the windows (like MainWindow) you add the implementation directly to DI, elsewhere I have seen code that has an interface to the view and then registers e.g. IMainWindow, MainWindow - like registering other dependencies. I don't see the point of creating an interface to the window, much like you show here. Is there any reason to? Similarly if using view models, would you create an interface to the view model? I can potentially see more use in that, but as view models are pretty tightly coupled to the view anyway and typically that's the main / only place to inject them, is it worth it?
thank you, amazing vid! :)
You are welcome.
33:00 Eventhough this is just a sample app. It would be good to have some sort of counter or list of open windows so if you kill the MainWindow, the childforms will close as well so you don't need to close them seperately.
Add each window/form into a collection when they're created.
override OnClosing in MainWindow and iterate each window in the collection and call Close().
Easy. In your App.xaml add ShutdownMode="OnMainWindowClose". When you close the main window all child windows are automatically closed.
Hi tim, thanks for another great video. I wanted to ask i have been using IServiceProvider, ServiceCollection and BuildServiceProvider Method till now for DI in wpf. Should i switch to using IHost now? what would be the difference.
IHost adds more than just DI. It adds logging, configuration, and more.
Great video
Thanks!
Great Cideo, As Always! I would love to see a video on using this in a WinUI 3 Desktop App. I was able to launch MainWindow as a service using OnLaunched instead of OnStartup and Activate instead of Show. Microsoft loves renaming everything for no reason. Unfortinatly, I was not able to find a Windows SDK App equivilent for OnExit :(
Thanks for the suggestion. Please add it to the list on the suggestion site so others can vote on it as well: suggestions.iamtimcorey.com/
Hi its Nice video explainig the DI Concept, May i know how to create view by closing the previous view and create new view like menu clicking to load new view
If you have a menu, you have a parent form. So the menu item would be the one displaying the new form.
Another awesome video. thanks, Tim.
but I have a question. Is it relevant to use Dotnet dependency injection with Caliburn micro instead of Caliburn micro's dependency injection?
Sure, you can do that.
hi Tim great video. Got to the end and you said its NOT! for .net framework, but for Core? Im doing .net framework because this app will hopefully be able to use older code? I want a Main form and then Child forms where its only 1 allowed (singleton) if possible. Will this example work in .net framework? Also
I have never used the Factorial arg in c# before variable name becomes VARIABLE_NAME!!! thats so interesting. Im a dinosaur from punched cards and functional programming
Yes, I was trying to be clear that I was using .NET Core (now just .NET) in the demo rather than .NET Framework. Things will be different in .NET Framework. You would need to use a third-party dependency injection library like Autofac, since DI is not built into .NET Framework.
@@IAmTimCorey you said that its core not .net framework. I needed to switch to classic old winforms that i used for years and can get things done, here with wpf it seems so fragile and limited choice of items to put in the designer. I started with the microsoft DI and it failed at the spot of using ? or ! that in 7.1 isnt there, use version 8.0? you cant. Not sure if DI is needed the only idea was to bring in outside code of unknown type or version. I went from doing forms, to embedded cpp to web and now forgot things, I hope to have many panels depending on what its doing, a Tab control could work where each one is its own blank canvas? Trying to drop 5 panels on top of each other hoping to bring back the way its done? if there are 5 or 6 buttons on the left each opens its own majority of the page with its own buttons, text input etc, if wpf can do that better great.
I did your example here maybe 5 times hoping to grasp it and its very well done and makes sense. repeating the task a few times helps to memorize it.
I want to capture video in WPF, using .net 6.0, but no resources/sample, could you help me
hmm... does this also apply to WinUi3 apps? They don't have an OnExit() method. Any thoughts Tim?
is there any play list for this tremendous subject and explaining?
I have a number of playlists on my channel that you can check out.
@IAmTimCorey
Thanks alot, i wish to see more design patterns in wpf, especially modern .net 6+
I want to use mediator pattern in wpf and have multiple threatds handling multiple things, so message passing between the components are done in the mediator
So the factory is for when you want a new instance every time you ask for it. (I thought 'Transient' already did that).
But most of the time you would want the same instance, if you are keeping track of state, navigation manager, etc.
Or am I wrong?
A factory can accomplish different tasks based upon its design. For instance, the HttpClientFactory will handle the lifetime of HttpClients internally so that they are properly recycled and reused in order to not exhaust the sockets on a computer. Another factory might create a new instance when requested, which is different than creating a new instance when the class is constructed.
You can create a playlist named .net 6 and put all videos related to .net 6 in that. It would be easier to find.
A lot of the content that isn't marked as .NET 6 is still relevant for .NET 6. That would confuse people, which is why I haven't done it.
Thanks for the great video, this helped me create Console Apps with DI, but what is the difference between Apphost.RunAsync() and StartAsync(), seems like the task from RunAsync is not returning !
I am glad it was so helpful.
Hi. I have a question about the IHost object. You make it nullable, but then you use the ! to override the compiler warning. You stated when you created it, that it needs to be nullable. Can you explain why?
Allow me to answer. It is nullable to avoid the warning.
Nullable reference types check whether fields and properties are assigned in the constructor when the members are not marked as nullable.
Tim chose to init the host in the lifecycle event so to avoid the not initialized warning he used the bang (!) symbol when accessing the nullable Host property.
You could new up the Host in the constructor of App class and assign the property there. Then you would not have to make it nullable. But putting logic in constructors are not advisable.
I’m not sure why Host is static. Though.
By default, the templates are not set up aa enforcing nullable reference type checks as errors. So all you get now are warnings.
@@marna_li It's just moving the warning from one, focused place to every usage of the property which essentially cannot or should not logically be null. The usage of NRTs is incredibly silly at times in this video.
@@marna_li Host is static so as to be accessible from the entire application, e.g. to access GetRequiredServices.
As for new-ing up the host in the constructor, that's precisely what Tim is doing.
Unless you mean new-ing up in the static constructor?
As always, thanks for the great content,
Usually in a main window, the need arises to call many child forms, for example: a form for sale another for financial transactions, another for some reports...etc
this could mount to tens of child forms for a complex business application,
adding a parameter for each type of child forms in the main window constructor feels very wrong,
is there another way to help in that scenario?
I’ve seen it done with an collection of generic viewmodels in an AppViewmodel type container. When a new form is required, the viewmodel for that form is created and added to the list, the UI then opens a generic form and using templates, displays the correct layout for that viewmodel. It’s not going to save code over what Tim has done, but it encapsulates the form logic into the viewmodel that owns the form.
@@turn1210
Thanks for your insightful comment
I really appreciate it.
@@ahmadkelany you’re welcome my friend 😊
very nice video, very helpful. would you do a basic tutorial on di in a blazor-hybrid-wpf project? in the microsoft docs tutorial they use services = new ServiceCollection() and Resources.Add("Services", services.BuildServiceProvider()); i followed your code sample to understand the differences, but it seems to me that the one created in app.xml has no relation to the "ServiceCollection" as created by MS example. i'm confused and would love to see a video explaining this. cheers
Thanks for the suggestion. Please add it to the list on the suggestion site so others can vote on it as well: suggestions.iamtimcorey.com/
Very useful video Tim. I am new to WPF and .Net and I am dealing with something like this. But I am stuck because I am passing the environment variable and want to call the WCF service binding uri for that passed environment variable. Is this achievable using this? It looks to me like I have to first add the service binding for all the environment before I can call it? Or am I doing something totally wrong? It looks redundant to me to add the same service just to get it working for all environments. For Example if I pass the environment variable user input as Dev1 then I want the to do something by calling the Dev 1 service to be called. If I pass dev2 then dev2 Uri to be called. QA then qa uri and so on.. Basically developing an exe application in WPF with .Net framework and they want me to pass the environment variable. Please advise. Thanks
tks very much, Please if we have for example ChiledForm that accept a IDataAccess as a parameter, how can I open it from another form without using Factory, I don’t want to pass a IDataAccess as a parameter when I call ChildForm.Show();
You would get the child form from dependency injection. That way it gets the dependencies it needs too.
@@IAmTimCorey the MainWindow is the parent form, i use Repository pattern, i pass the IRepo as a parameter, when i pass it to the constructor of MainWindow this gives me error:
system.invalidoperationexception: 'unable to resolve service for type 'dataaccess.dbcontext' while attempting to activate 'dataaccess.repositories.genericrepository`1[repo.models.user]'.'
then i create a variable for IRepo with new keyword and i pass it to childForm to open it, but if i do i must to pass a dbContext to create the IRepo variable:
IGenericRepository repo = new GenericRepository(new DataAccess.DataContext());
i don't want call or Pass DbContext in my frontend.
tks
Thank you
You are welcome.
What if you need parameters for the factory.Create() function? I usually use parameters like fullscreen = true, size, center = true/false etc when creating windows using a helper function (and different parameters for different types of pre-defined utility windows -> e.g. a "form popup window (gets an UserControl as a parameter)" will be displayed without minimize/maximize box and a "fullscreen image displayer" (gets a byte[] or an Image as a parameter) will be displayed without borders and without title and buttoms)
Is the solution creating a different IAbstractFactory for every of these types of windows? (one for no params, one for a "usercontrol form displayer", one for "image displayer") and thus getting 3 IAbstractFactory types with each one prescribing different params in the .Create() function?
I don't know if this might help, but Dependency Injection works best with what is called Parameter objects, where you pass your parameters as Object and you define your classes as generics, this also helps you when have multiple implementations or decorators .
I showed how to do that in the previous video. I put the time marker at the time when we actually send parameters, so you can see how it can be done: ruclips.net/video/2PXAfSfvRKY/видео.html
@@IAmTimCorey Thank you very much.
What is the best way to pass parametr between 2 forms? For example object to edit?
It depends on your situation, but remember that a form is just a class. You can pass in constructor parameters, you can subscribe to events, etc.
Could you show the same for Windows Forms and how to use it with UserControls?
Thanks for the suggestion. Please add it to the list on the suggestion site so others can vote on it as well: suggestions.iamtimcorey.com/
Hi Tim, do you have any course for non us people, I've seen on your site but after converting to us dollars it became too expensive. Can you make some cheaper modules?
The paid content is used to fund the free content. That's why we keep it at the price we do. Lowering the price to accommodate more cultures and economies would actually reduce our capacity to make more free content. However, because of the pricing being where it is, we have been able to give away three full courses here on RUclips (TimCo Retail Manager, Tournament Tracker, and Suggestion App). We have over 11 days worth of videos here on the channel and more is being added every week.
Is there anyway to do dependency injection through xaml? Like injecting view models with xaml?
You can set the data context in xaml, but that will only give you an empty view model, it won't have anything populated. You can't put data into it through xaml.
Reference your data context here
That's the only way I know in xaml to get a VM going, everything else involves varying levels of C#
How did you use assignment to dataAccessInfo not creating this form property?
The dataAccessInfo is the TextBlock on WPF form. That is what I named it. So, it has a bunch of properties for that TextBlock, including the Text property. That's the property we used to put text on the form.
How could I add existing ViewModel to a FormFactory as opposed to the View creating its own ViewModel?
Totally lost on this one Tim. I not in the world of WPF so this is not helping.
I have a Services Project that calls a Class Project method that then needs to call a EF Core using Repository and Interface.
As a Blazor project, this all works out of the box with a simple @inject. Why so hard to get this to work in a Services Project.
Do you have a video that shows close to this type of project setup. Services Project, calling a Class Project that calls Repository\Interface Project to do the EF things?
It sounds like you just need to get dependency injection set up in your project. Then you just ask for what you need and get it. It should be no different than Blazor at that point.
One would think Tim but it's seem not that easy. I trying Autofac to see I could in this.
In a Blazor project I simple Add
@inject IUsersRepository _userRepository
And then I can call everthing.
In a Services Project, no.
Here what I have in the Services project but if I try to call a method in a IWhateEver, it a no go
public static void Main(string[] args)
{
var builder = new ConfigurationBuilder()
.AddJsonFile($"appsettings.json", true, true);
BuildConfig(builder);
var config = builder.Build();
var dbWaterConsentsCoreConnection = config["ConnectionStrings:WaterConsentsCoreConnectionString"];
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddHostedService();
services.AddDbContext(options => options.UseSqlServer(dbWaterConsentsCoreConnection));
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
services.AddTransient();
services.AddTransient();
services.AddTransient();
})
.Build();
//And my go at using Autofac.
var builderAutofac = new ContainerBuilder();
builderAutofac.RegisterModule();
builderAutofac.RegisterModule();
builderAutofac.RegisterType();
builderAutofac.RegisterModule();
builderAutofac.RegisterType()
.As()
.SingleInstance();
builderAutofac.RegisterType()
.WithParameter("options", DbContextOptionsFactory.Get(dbWaterConsentsCoreConnection))
.InstancePerLifetimeScope();
IOTDevicesRepository whyDontyouwork = new();
whyDontyouwork.Get(1);
var container = builderAutofac.Build();
var studentRepository = container.Resolve();
studentRepository.Print(oStudent);
//This will not work.
var iotRepository = container.Resolve();
var pleasework = iotRepository.Get(1);
host.Run();
}
very tanks
You are welcome.
if i use dotnet framework instead of dotnet6 will this example not work?
No, it will not.
Microsoft.Extensions.DependencyInjection.Abstractions
Can someone explain what is this package used for
It gives us the keywords for accessing things more easily from Appsettings. It is an interfaces and abstractions library that other libraries build off of, so we can use it to get access to those same abstractions.
@@IAmTimCoreyI have another question if you can answer it. I have a list in WPF, and each item in the list has specific commands associated with it. When I click on a particular item, I want to change something on the view model. Each of my items depends on the view model, as well as on some other information. How can I correctly instantiate these items for my list? I cannot use a factory because it's not just the view model that I depend on; I also need to include additional information such as name, ID, quantity, etc.
I have one question do you really see WPF now being used in the market?
Absolutely. The key is that a lot of desktop apps are really old (so they are still WinForms). For newer apps (made in the last 10-15 years), WPF has been a solid choice so a lot of companies have chosen it.
@@IAmTimCorey I think companies are going with web apps now? Every desktop app is being made into web app.
Would like to know that from Tim as well. I see a trend more towards webapps and away from desktop-apps...
Is it possible to do a video about Win UI 3 vs WPF.
Thanks for the suggestion. Please add it to the list on the suggestion site so others can vote on it as well: suggestions.iamtimcorey.com/
Спасибо
You are welcome.
How to use this with MVVM pattern.
There is no real change. You just get your ViewModels from dependency injection rather than instantiating them yourself.
how do you get child form from a child form than?
The same way you get the first child form. You specify what each form depends on in the constructor. When DI goes to satisfy the main form, it will see that it needs a child form. When it goes to provide the child form, it will see that the child form depends on a child form of its own. It will get the grandchild form first and work its way up the chain.
@@IAmTimCorey and if creation require dynamic data?
You would set up a factory in you DI system or pass in the data after creation of the generic class instance.
4:00 How app starts
6:00 Microsoft built-int injection package installation
I think everyone now is making only web applications
No, the desktop app is still alive and well. They just aren’t used as much for sample projects. When you look at what businesses build (the people employing developers), there are still a ton that use desktop apps. They are the right choice in a lot of situations.
Am I the only one who gets confused by the name Dependency Injection? I would have called it Global Reference or something.
The reason it is called that (and this isn't C#-specific) is because we are injecting our resolved instances into classes when they state they have a dependency. So instead of a class having the line "var log = new Serilog()" in it somewhere, the class asks for a logger. The difference is that in the first way, the class forces the application to take on the Serilog dependency. In the second way, the class asks for some type of logger. It depends on a logger, but it doesn't care which one. Just one that satisfies the interface. So, when the application runs, the dependency injection system can figure out which logger to create and then it injects that instance into the class that requests it.
@@IAmTimCorey Thanks for the explanation and the great content.
Hi Tim, I tried what you show but have encountered an issue. In my App.xaml, I have a Style defined in my ResourceDictionary with x:Key="GeneralButton". Over in my MainView.xaml, I bind to this style like so: Style="{StaticResource ResourceKey=GeneralButton}". However, in my MainView.xaml.cs, I run into an error when executing the InitializeComponent() line: "'System.Windows.Markup.XamlParseException... 'System.Windows.StaticResourceExtensions' threw an exceptioon... Exception: Cannot find resource named 'GeneralButton'. Resource names are case sensitive". My understanding is that before I was subscribed to the Application_Startup event: , which seems to have included an initialization of the ResourceDictionary in my App.xaml. When I override OnStartup, however, this seems to not take effect. I was wondering if you know how to keep my ResourceDictionary where it is, as well as overriding OnStartup. This approach seems more elegant to me than resubscribing to the Application_OnStartup event or putting my Style definition in MainView.xaml (I want it to be defined at the application level).
Great video by the way - been learning a lot from you! I love dependency injection.
Sorry, I don't have a good example to show you and I'm not sure off of the top of my head. Maybe ask on Stack Overflow.
Hey, at 28:42 I miss the point of ignoring the warning instead of using GetRequiredService() instead. What's the reason behind that?
I was in the head-space of thinking about nulls and focused on addressing that instead of remembering to require the service. 😆
@@IAmTimCorey Haha, I see.
In my option you should overall limit the use of the bang operator to minimum.
Don't know how experienced you are with Typescript but it's not uncommon to see it outright banned in some scenarios in many typescript projects. It's part of the reason why cases like this immediately pop a "warning" in my head as I see it more like a hack around pretty much an unsolvable problem of compiler not always knowing what logically is or is not possible, rather than something you should sprinkle around in your code.
Just my 2 cents 🙂
I tried creating something similar with my own DataAccess class, nothing special to it. I register it as a transient
services.AddTransient();
Later in a different class I try to get the service by calling AppHost.services.GetRequiredService();
but this throws an error: "No service for DataAccess has been registered". Does anyone have an idea of what could be causing this issue?
I forgot to mention that I created another data access class that uses the same IDataAccess interface. Could this be causing the issue?
You registered it as an IDataAccess but you are trying to access it using DataAccess. You need to access it using whatever you registered it as.
@@IAmTimCorey I see. Thank you for the clarification.