You are the best instructor on youtube. You just understand what have to be told to make people to understand the topic. It's a gift that few people have.
Tim, you're amazing at explaining all these code related functionality. Thanks to your pedagogic skills I've actually understood (I think) things I almost given up on understanding.
51:00 Great video! I wanted to give another option for injection of different implementations of an interface and that is to use a factory pattern. So you would inject a factory class that can produce those types of interfaces. That is how I have done it. My specific implementation was that I needed to validate data that has different structures but one common field that defines the pattern used so I use that as a parameter to the factory method. Each of the validations are available in the container and the factory uses the ServiceProvider to extract the interface.
That can be a good solution when needed, but I would encourage you to avoid it as much as possible. Once you start down that road, it can be easy to justify doing this for everything. Next thing you know, you have a complex DI/factory system that is a nightmare to maintain. It is an added complexity that you don't often need.
@@IAmTimCorey What would you guys recommend for reducing setup complexity? Specifically, I'd like to abstract data access, because I want to keep my options open as to what kind of data storage is going to be used. Let's say it's either MSSql or SQLite. So there would be an IUserData interface for user data CRUD and concrete UserDataMSSql and UserDataSQLite implementations. So far so good, but this is going to grow quite a bit as I'm adding more data models. Would you just write a big if-statement handling the DI setup, depending on storage type? Use a factory? Or maybe put this in the app settings somehow? Thanks! --- EDIT: Looks like this kind of setup can be simplified with generics: services.AddSingleton(typeof(IDataStorage), typeof(SQLiteService)); then requesting a concrete service from DI with IDataStorage service = App.Current.Services.GetService();
Came here to consolidate my understanding of .NET DI, left here also learning some great info about logging including your string interpolation tip. Thanks Tim 😊👍
It's sometimes little side effects, like writing ctor to create a constructor, or a semicolon after the namespace, something not really the intended message of the video, but still useful. Everybody can discover something valuable. Even if you think you know it all.
That's really cool! Finally I've understood it ! Using Random values for explanation is really great, clearly I've got the picture of DI ! ( I should have watched your video before!) Thanks a lot!
@@IAmTimCorey Hi Tim, I am a big fan of your video and would like to ask to see if you have any videos/materials talking about using C# and .NET to build standalone desktop application? In particular, I am very interested to use C# to do some data processing and chart plotting and making it a standalone tools for the engineers. Thank you very much!!! We can talk offline as well
Tim, in this video, I thought I understood something but then when you ran the code, I guess I must have misunderstood it. I'm not sure if this is relevant but I think it is. I've stopped and grabbed a screen snippet for myself at 40:22 in the video so if you explain this later in the video, my apologies upfront for not watching further. Just before 40:22, you were extremely clear (I thought) that the whole purpose of using logger.LogInformation("Displaying values of {Value1} and {Value2}", logic.Value1, logic.Value2) was so that in the log, we would get a string literal of "Displaying values of {Value1} and {Value2}" followed by a column of the value stored in logic.Value1 followed by a column of the value stored in logic.Value2. However, at 40:22 in the video where I took my screen snippet, you were showing the output window where the logger would log the values and in that window, your logger appears to be showing one literal of "Displaying values of 996 and 851" which IS replacing the {Value1} and {Value2} portions of the log with the actual values stored in the logic fields exposed by those properties and it doesn't show the columns of the logger at all like you had said which is exactly what you had just said that it wouldn't do if we used the syntax that you used. So now I'm confused and I'm not even sure if this has to do with dependency injection (Did a wrong logger get injected or what?) or if it has more to do with logging (which will be a video on my to-do list to watch now)... Could you please, especially in the event that this is due to a wrong logger being injected, explain why yours didn't work (at least the way I understood you saying that it should and would)? It seems like you're moving right along with the video here but maybe that's the whole point and you're about to explain. I'm just not sure and feeling lost now. I love all of your videos and how in-depth you are at explaining this stuff! I'm such a Virgo - I don't just google for snippets that work; I want to understand the code and HOW it works so your under-the-hood explanations are always so welcome in my world. I'm just lost and frustrated on this one as I've rewound and watched your prior discussions twice and what you were saying made perfect sense to me but then wham this output is nothing like what you had said I should expect and nothing like what my code-brain was expecting so please tell me what I'm missing! Thanks as always. You're in my top three youtubers and I can't get enough! (Your Dapper videos the best ever for the record!)
Serilog allows us to capture structured logs. However, our logging sink needs to support those structured logs. The console sink does not support structured logs. However, it still falls back to "normal" logs in those cases. When you then hook up Seq as a sink instead (or along with the Console), you will get your structured logging broken out. This video wasn't focused on Serilog and Seq, though. Rather, it was focused on using dependency injection to swap out your logger. If you want more depth on Serilog, Seq, and structured logging, check out this video: ruclips.net/video/_iryZxv8Rxw/видео.html
Dependency Injection is amazing, but have problems with unit testing it with mocked objects. It would be amazing if you make a video about dependency injection's increased testability. Thanks for the C# content, like always!
Do you mean beyond what I covered here? ruclips.net/video/DwbYxP-etMY/видео.html If so, please add it to the list on the suggestion site so others can vote on it as well: suggestions.iamtimcorey.com/
Best explanation and I just started to looking for DI, so I'm really happy that i run into the best one at first, it's not something happening all the time when you are Junior 😂. Simply the best, Tim! Thanks man!
Whenever I want to understand something in .Net I ALWAYS go to your videos first! This is so well explained, thank you. I am hitting a bit of a wall now though - trying to implement DI in a .Net Core Class Library so I can do unit testing with mock classes. Hmm, no program.cs for starters. Any pointers please? And very Happy Christmas if you read this in time! All the best for 2025 Tim!
I'm glad my content has been helpful (and Merry Christmas to you). If you are working with a class library, you are creating the dependencies, but you are not able to actually set up dependency injection. That is because the class library is not the project that gets executed. A UI project gets executed and it can use a library. You can see an example of this in the Suggestion Site playlist here on RUclips. I use a class library there and it is used in dependency injection.
@@IAmTimCorey Many thanks Tim! I appreciate your explanation. FWIW I'm still working out how I am going to test the class library that I am writing (sorry I didn't make that clear that the library is mine). I'm finding more clues in all your great content as I go! :) The client of the class library is a large, old VB6 application - the class library I am coding is one of the steps towards migrating it from VB6 to .Net. It'll be worth it in the end haha! :)
You can test the class library with something like XUnit. It won't need to implement dependency injection because you will do that manually. If a class needs logger and data access dependencies, you would probably give it mocked versions of both since you are testing the specific unit, not the associated dependencies.
Trying to convert a Windows Forms app to .NET Core. Changing to use DI as well. Couple of questions. If you have lots of services that a process uses do you need to create a constructor that has many parameter's? Or is there a way inside the component to be able to ask for the service when/if needed?
You need to provide them through the constructor. That's one of the benefits of dependency injection - you declare your dependencies up front instead of burying them in the code. By putting them all up front, you may have a dozen or more dependencies. That seems like a lot in the constructor, but that is just exposing what you are actually doing in the code. If you think that is too many dependencies, you need to clean up your code to not depend on as many things. Reducing your code complexity will be a big one.
I recently ran into the Singleton vs. Transient use for a project I started with Tim's recent Open API video where Singletons are used for the database access. But the tutorial I followed about Bearer Tokens and Refresh Tokens used Transients, and I had to look up the difference. Great video showing the difference and more info on DI.
How would you go about creating a multi-tenant .Net 6 MVC website with single code base/separate database per tenant, where most users will have access to a single tenant but some users will have access to multiple tenants? I want to use the same host name for all tenants in the event I need to use 3rd party controls that cost extra for additional hosts.
How does the server know when to release memory for the scoped dependencies? My understanding is that http is stateless. Is there a http communication to the server when a tab or browser window is closed?
Great video! A suggestion would be to use concrete, practical names for folders and classes, rather than just "Logic" and "DemoLogic". Will help the viewer understand a lot better IMO
Is it possible to inject a dependency into a class without being forced to use the constructor? Is there a handy way similar to @inject that exist for classes not linked to a view?
Hi, just enlisted to your .Net intro course. looking forward to it after watching this video and the one on console applications with dependency injection. I'm still wondering though about the following: with a .Net template I kind of get it. Every class can get access to the services container and request a service. Good for decoupling. But with your video on the console I got kind of confused. When I instantiate an object from let's say main, that object does not have access to services, right? not even if the console has set up a host. my guess is that when you have template code like a Web API project, then the 'usecontrollers' thing in main takes care of making sure that all controllers get access to the host. Does your dependency injection course go deeper into this? because for me it's now still 'magic' to see that the classes inside a WebAPI or MVC templated project do have access to the services container, while in the console version I still have to pass the host. (or I'm doing it wrong, that's also very possible) anyway, the question is does your dependency injection course go deeper into how the classes get access to the host/services?
35:07 How would you use this .NET Core structured Logging in combination with a StringBuilder? Let's say we have a List and want to display the IDs of all objects where a specific property is false for example. In this case I currently have a StringBuilder, iterate through the List, append to the builder whenever a condition is true (currently with append() and string-interpolation), and then write the result into the log file just once. Should I stay with that approach or rather explicitly call logger.LogWarning() or logger.LogDebug() for every affected object?
It depends. If you just want a string and don't want to filter or query on any of the data in that string, StringBuilder is fine. Otherwise, you should consider another route. You could convert the list to JSON and pass that in as a parameter of your log statement. Or you could log each line.
Thanks a lot for this valuable explanaiton. in case you have a new class, also, you will create an interface to it to register it, so, the place you want to consume it, you have to change the interface injection to the new interface, please correct me if I'm wrong. Also, I have inheritance "Abstract Class" with some common implementation for subclasses, using DI with inheritance is impossible, because they are different concepts. I tried it a lot, I didn't succeed. Appreciate if you correct me if I'm wrong. Thanks
So if I have the service in one project and the "consumer" in another, I necessarily need a third project, to put the interface in, and have both of the first two projects referecing it, right ? Just thinking where to put the interface, when organizing projects.
My basic project to save Xlsx ko Xlsm works fine in my computer but it shows error and crashes at "saves as" line in others computer. I used Ms excel interop for it. What do u think would be a reason for error?
I was able to pin point error upto "save as" Line. But I don't know how I can resolve the issue. My. Computer has 2019 office and all. Computer I tested had older version.
That's probably the issue. Excel Interop uses the version of Excel installed on the computer. That's the downside of using a library like that - you need to have Excel installed in order for it to work.
Hi! I'm following this example in as a Blazor Web App .net8 template in vstudio 2022 17.10.5 with Server render mode (per page/component). I can't get the AddScoped to work, as it always behaves like Transient. Singleton and Transient work as expected but Scoped always instantiates a new object every time. What's the diference? **edit:** `@rendermode @(new InteractiveServerRenderMode(prerender: false))` makes it behave like expected but not sure why?
Thank you❤!! Tim!! I have watched everything for di in youtube and in your site. I am just stacked in a specific situation. 1. Should i avoid static methods and use singleton instead? 2. In which case i i need to use singleton and in which transient? I will give you an example on this. I have a class that includes only one method. No variables just one method called GetCustomers(). In this method i making a sql server query for get and return customers. What is the best approach for this class? Singleton, static method or transient??
There are reasons for static and reasons for singletons. I have videos covering those topics. As for your specific situation, it depends. If the method opens a connection, makes the call, and closes the connection (it is self-contained), then it is probably best as a singleton. If the method stores state of any kind, it might be better as a scoped or even transient.
@@IAmTimCorey Thank you Tim! what you mean . Please give me an example in which senario do you mean? Do you have videos in your site that covering difference between singleton and trasient and static method in depth? Please give me the link
Tim - would be great to see an updated video on how to set up DI for typical console apps in the .NET Core model (versus the old 2020 version). I have web apps that use the same master data over a session. I've been using ProtectedBrowserSession for this, but would it be better to use Scoped DI for this data? What are the best ways to make the call as to approach on this?
I'm not sure if I understand. You are asking about a console app but your example is a web app. I know that web apps are just console apps that have additional things on top, but that's a key distinction. I have a video here on RUclips that shows you how to add dependency injection in a console application. I also have videos showing you how to use dependency injection in a web app (this video included). As for saving your data over a session, I can't really give you a specific answer since there is a lot more questions to ask. However, in general you should use the web project type that best fits your needs. For example, Blazor Server is very good at having data over multiple calls (maintaining state). So is Blazor WebAssembly. MVC, Razor Pages, and API are not designed to do that but can. It also depends on your data. In general with a stateless website, you would want to remember the ID of the data locally and then request it again later rather than storing all of the data (that can be expensive and dangerous). Scoped DI probably isn't the right choice here, but I can't say for certain.
@@IAmTimCorey Sorry for the confusion. I have a couple of scenarios with .NET 6 and I'm trying to implement DI properly across both. We use a standard N-Tier solution structure, with BLL, DAL, Models, etc. projects being simple libraries that can be used with Console or Blazor as the "presentation" layer. In Blazor/MVC apps, I'm able to set up DI using the builder.service and adding the [Inject] to the component's class file. However, I cannot figure out how to accomplish the same paradigm within the new .NET 6 Console app. The [Inject] annotations do not appear to work (or I have some misunderstandings of how it should work). I understand that we can just instantiate a class using its constructor to pass in dependencies, but I thought there was a way to use the [Inject] annotation to automatically pick up the particular service instance. Maybe I'm wrong on this. Also, I understand that we want to instantiate the service once at startup, then pass it around to other solution project classes. Keep it clean and DRY. In my case, I want to instantiate the ProtectedBrowserStorage at startup, then pass it to the BLL where I have a repo manage what goes into and out of the session state. But for whatever reason, the session instance is NULL even if passed to a constructor. I found this to be true with a repository instance as well. However, if I instantiate the session and repo and skip the builder.Service, I can pass them into other classes without issue. Of course, in all of my attempts, I probably confused myself and got a wire crossed somewhere. Trying to wrap my head around it. As you can see, I probably need a concise tutorial on how to get it to work the right way. Love your content! Keep it up.
I cannot wrap my head around any scenario where switching from logic to betterLogic is the case. Why not just change the classes? This comes from absence of experience tho. Is this when you have different projects which take data from project A to project B and project C has the interfaces?
Tim, Thank you that make it understanle. Q: in case i have Load Balancing for the web server, how exactlly it will affact the Singleton process? Will the singelton instance be created once? or several times per each server instance? Unfortunaterlly, I don't have the option to implament it and checking live by myself. I just know that in the very old past, the answer was object instance per server instance. Is it different in .net 6?
It would be once per server. In a load balancing situation, each instance only knows about itself. If only one of the server instances initialized the singleton, the rest wouldn't have it to use.
Another great tutorial. Looking for advice... I have a validator class using an interface, which more than one methods in the class will validate a single model(DTO/POCO). I planned on passing this model instance in the constructor, but am hitting issues with dependency injection and that it doesn't know about the POCO model class. How should I approach this? I prefer not to pass the model around to every method, was also hoping to avoid using a setter. Using constructor seemed to make sense so that the class has what it needs but doesn't seem to work with DI.
hello tim thank you for the content just a suggestion when you explained the logger is good doing shorts on youtube about tips and tricks like that would be great thank you
@49:59 in Spring Boot we can easily get different beans for same interface just by mentioning the bean name or id during creation and wiring the bean with the same name to the target variable. Most of the things are better in Spring Boot except for few things like short hand syntaxes, build size and memory consumption which are better in .net.
Mentioning the bean name is the issue, though. Then you have coupling. That's something you need to be careful of. If you cannot swap out an element without changing your underlying code, you should probably rethink how you are doing dependency injection. Otherwise, you are basically creating distributed tight coupling.
Hm... you are also correct at your end, but in dotnet as well if you want to change a dependency you will to change in code i.e. in Program.cs file. In Spring Boot dependencies are created automagically using @Component or related stereotype annotations. These dependencies can be injected using constructor. This saves lots of developer's effort. In dotnet you will have to manually inject the dependency from Program.cs everytime you create the dependency class. In Spring Boot as well we can keep all the dependency at one java config file using @Bean annotation above methods returning bean. But it is not followed much for services and controllers because whole point is that we should be able to change the implementation of dependency by changing one line of code, which can still be done by removing @Component annotations from the previous dependency classes and adding in required ones.
Now i understand how to inject a service in razor or .cs-code-behind file. But how to inject it in a class, in which a complex businesslogic is encapsulated for background work (located in an own project) ?
The same way. Your UI layer handles the dependency injection setup, regardless of what that UI layer is. In the case of a background service, the UI is the project that starts and stops the application.
@@IAmTimCorey Thanks for your answer and your great videos, but I haven't quite understood it yet: Is the dependency passed to the backgroundjob via the constructor (constructor injection)? Or can this dependency also be injected via a corresponding keyword similar to @inject? My problem is that I cannot use @inject in a normal cs class.
Why I can't have a model like a LIst as a scoped dependency injection so I can work with this list at different pages? It is not a database synced list, it just my current selection (probably not even a user at this time)
You technically can and for demo purposes (I just verified that it works), that would work, but it isn't the right solution for models. Especially since you usually want to overwrite the List instance, which is not something you should do with dependencies from DI. Models don't need to come from DI because they aren't dependencies, just data.
How does AddScoped works with cookies or session. If I have logged in I can open new tab and still stay logged in, will AddScoped return me same instance or create new instance? I suppose it will create new instance, if it does how to handle it?
AddScoped is on the server, so it doesn't know about cookies or anything else client-side. If you open a new tab, you get new instances of your classes that are marked as scoped. I'm not sure what you mean by "how to handle it". If you are asking how you stay logged in on different browser tabs, it depends on how your authentication system works. If you are using a bearer token, just store it in LocalStorage. Then, each tab can have access to it and you are set.
one probelm I ran into was having two concrete implementations that shared a interface that I needed in different situations. do you have a good solution to this issue?
Yes easy with multiple ways, One way is reguster the concrete class for both and request the one cobcrete or both as you need. Another yoy can reciwcw both objects and select the one you like with linq query
@@Holyflare it wasnt mwntioned how to allow both, he said change the interface and not doing this way. Sometime the di depend on dynamic runtime and both can be requested. The way I did it, do Services.AddTransient(); Services.AddTransient(); Then in ctor used the Concrete signature to get the one you like
I did say you could do what you are suggesting. I also said you could put both in and then get an array of items. What you are doing is creating a hard dependency, which reduces the benefits of dependency injection. Why not just create two different interfaces, if you really want two different class instance types?
Just register them like normal. It will just work. The key will be how to get those implementations. But for that, you need to know how to tell the system which one you want. You can either as for an IEnumerable of that interface and get all of the implementations or you can ask for one (and get the last one) or you need to have a way to differentiate the implementations.
@@IAmTimCorey I believe i was not able to describe the question clearly. I wanted to ask, suppose a service implements interface1 & interface2. Now how to register it in startup? If it implemented only interface1, in the startup I would only say services.AddSingleton() But as i said, the service implemented 2 interface, how should I register it?
You could register it twice if you want to access only one interface at a time. Or you could register just the one interface and cast to the other interface when needed. Or you could create one super-interface that implemented both interface1 and interface2 and then use that to register the implementation.
How does .NET know that builder.Host.UseSerilog overrides the default logger. Does Serilog impliment a needed interface of that is the trigger? Great video!
Very nice explanation. One thing I never heard was that an Interface needs a concrete class to implement it. I know this is not a vid on Interfaces but ... A brief explanation about programming to Interfaces and not classes would go a long way.
Is it really necessary to always extract an interface for every class you need for DI? Because the interface is just used for that one implementation. Is this not against the concept of YAGNI? I mean why not injecting the concrete class? Whats the disadvantage?
Inject logging or just any class? If you want to inject any class, just put that class in the constructor. If you want to inject a logger, put "Logger log" as a parameter in your constructor.
@@IAmTimCorey Thank you! I'm currently watching your appsettings.json video, and there is a small snippet in there where you show this! I've wasted hours and hours messing around with code trying to figure it out, you showed it in about 20 seconds. I love it!
Hi Tim, In DI I always struggle when in some projects people use different ways - serviceCollection.AddScoped(); serviceCollection.AddScoped(sp => sp.GetRequiredService()); I am aware of the scopes but what is the difference between these two lines. When to use the first one or second one or what is the use of using both ? Please help. Thank you in advance.
Tim, if I am trying to make a list of fake employees to populate a demo application with, is it bad practice to add scoped dependency injection with a DemoDatabase class? (interfaced of course). I want the user to have the ability to CRUD employees and have it reset when they leave the application. But I don't want that data to persist anywhere and I don't need an actual database - it is just so IRL employers can test my application in browser and assess its quality. Thank you for your great tutorials and for taking your time to respond to commenters - I have seen you recently reply to people on videos from years ago! We appreciate the dedication!
That seems like a fine solution. As long as you understand the dangers (and you do), and you know that it is a demo and not something you should do for a "real" production app, go ahead and implement it.
would you please make a video explaining to us "the real benefits" of "struct/abstract/.... extra" or they are there abandoned and they have no real usage in our daily usage in programming
It depends on the complexity of your app. Console apps can be simple enough that dependency injection isn't necessary. However, if they grow, having dependency injection can be a real benefit. In that case, you would want to let DI handle the instantiation.
Hey Tim, Thanks for the excellent explanation. I've watched your DI in WPF but I am still left with a lot of questions. Should I include all views and view models as dependencies? Can my view models have models as constructor arguments? Is it best to keep all constructor arguments of type interfaces?
Views? No. ViewModels? Yes. ViewModels are classes and they have dependencies that need to be fulfilled by the DI container. As for constructor arguments, technically you can but the ideal situation is to avoid that and pass the value in after instantiation.
@@IAmTimCorey I guess I thought views are registered because in your WPF video you had registered that main window and child forms. Was that only for demonstration purposes?
Thank you Tim. thank you for your efforts. I am not a .NET developer but interested to learn it. Anyway what makes me check your tutorial on dependency injection(DI) is that I've noticed that in many .NET tutorial they intensively use DI, nearly every class they add to the system they add it to DI. For me I think using DI can be useful only in places where the class can be used in multiple places, such as the Logger you mentioned in your video. On the other hand adding all models to DI will make the code in the program complected with nearly no need for that as most of the classes will only be used once or tow times. What do you think? is it practical to add all models to DI?
I don't add models to DI normally. Those don't create dependencies. However, all other classes get added to DI all the time. There are very few apps where I don't use DI. It allows for easier/better upgrades, less coupling, and easier testing. Here is a video on the Dependency Inversion Principle (the D in SOLID) that explains this concept better (DI is an implementation of this principle - they aren't the same, which I will explain in the video): ruclips.net/video/NnZZMkwI6KI/видео.html
You are the best instructor on youtube. You just understand what have to be told to make people to understand the topic. It's a gift that few people have.
Thank you!
Totally agree with you!
Tim is great
Thanks!
Thank you!
Tim, you're amazing at explaining all these code related functionality. Thanks to your pedagogic skills I've actually understood (I think) things I almost given up on understanding.
You are welcome.
what a timing! that's exactly what I was looking for, thank you so much.
You are welcome.
@IAmTimCorey and you, kind sir, are heaven sent
Same!
So called complex topic explained in a super simple manner. You're awesome
Thank you!
I tried to understand DI for so long, finally got it thanks to you
I am glad it was so helpful.
bestest free course I am ever watching. Thank you very much
You are welcome.
51:00 Great video! I wanted to give another option for injection of different implementations of an interface and that is to use a factory pattern. So you would inject a factory class that can produce those types of interfaces. That is how I have done it. My specific implementation was that I needed to validate data that has different structures but one common field that defines the pattern used so I use that as a parameter to the factory method. Each of the validations are available in the container and the factory uses the ServiceProvider to extract the interface.
My thought also.
That can be a good solution when needed, but I would encourage you to avoid it as much as possible. Once you start down that road, it can be easy to justify doing this for everything. Next thing you know, you have a complex DI/factory system that is a nightmare to maintain. It is an added complexity that you don't often need.
@@IAmTimCorey What would you guys recommend for reducing setup complexity? Specifically, I'd like to abstract data access, because I want to keep my options open as to what kind of data storage is going to be used. Let's say it's either MSSql or SQLite. So there would be an IUserData interface for user data CRUD and concrete UserDataMSSql and UserDataSQLite implementations. So far so good, but this is going to grow quite a bit as I'm adding more data models. Would you just write a big if-statement handling the DI setup, depending on storage type? Use a factory? Or maybe put this in the app settings somehow? Thanks! --- EDIT: Looks like this kind of setup can be simplified with generics:
services.AddSingleton(typeof(IDataStorage), typeof(SQLiteService));
then requesting a concrete service from DI with
IDataStorage service = App.Current.Services.GetService();
I vote for video to demostrate how to setup dependency injection for console app. It would round-out this discussion. Thanks!
You are welcome.
Tank you Tim it was the best Dependency injection course i've ever seen.
You are welcome.
Best video on DI in .Net 6.0. It helped me to understand DI in better way.
I am glad it was so helpful.
Came here to consolidate my understanding of .NET DI, left here also learning some great info about logging including your string interpolation tip. Thanks Tim 😊👍
I am glad it was so helpful.
My main complaint is that I never found your videos before! Succinct, well thought out and a great, clear voice. What more could one ask for?
I’m glad you enjoy them.
Hey Tim. Another great presentation. I learn something new every time I watch your videos. Thank you for the service you provide the community
You are welcome.
It's sometimes little side effects, like writing ctor to create a constructor, or a semicolon after the namespace, something not really the intended message of the video, but still useful. Everybody can discover something valuable. Even if you think you know it all.
That's really cool! Finally I've understood it ! Using Random values for explanation is really great, clearly I've got the picture of DI ! ( I should have watched your video before!) Thanks a lot!
Glad it helped!
@@IAmTimCorey absolutely helped! Thanks! Going to check your courses!
Tack!
Thank you!
Thank you Tim.
Your videos are very useful. I really appreciate your efforts in helping us.
You are welcome.
@@IAmTimCorey Hi Tim, I am a big fan of your video and would like to ask to see if you have any videos/materials talking about using C# and .NET to build standalone desktop application? In particular, I am very interested to use C# to do some data processing and chart plotting and making it a standalone tools for the engineers. Thank you very much!!! We can talk offline as well
Incredibly useful as always. This answered a whole bunch of questions I had and I loved the discussion about the pros and cons of various approaches.
Glad it was helpful!
Thanks a lot for this very good presentation Tim. We need to stay focus regarding the number of interesting point provided ;)!
You are welcome.
That's what am looking for loooong time . special thanx for you Tim Corey
You are welcome.
Outstanding explanations! As usual.
Thank you!
@@IAmTimCorey no! THANK YOU TIM!
No words are enough to say how great info this video is. Just gratitude 💯💯💯💯
Glad it was helpful!
Very Clear Description for DI Thanks TIM
You are welcome.
Thank you sir, you are my guy for C#! Thanks for sharing the knowledge!
You are welcome.
Tim, in this video, I thought I understood something but then when you ran the code, I guess I must have misunderstood it. I'm not sure if this is relevant but I think it is. I've stopped and grabbed a screen snippet for myself at 40:22 in the video so if you explain this later in the video, my apologies upfront for not watching further. Just before 40:22, you were extremely clear (I thought) that the whole purpose of using logger.LogInformation("Displaying values of {Value1} and {Value2}", logic.Value1, logic.Value2) was so that in the log, we would get a string literal of "Displaying values of {Value1} and {Value2}" followed by a column of the value stored in logic.Value1 followed by a column of the value stored in logic.Value2. However, at 40:22 in the video where I took my screen snippet, you were showing the output window where the logger would log the values and in that window, your logger appears to be showing one literal of "Displaying values of 996 and 851" which IS replacing the {Value1} and {Value2} portions of the log with the actual values stored in the logic fields exposed by those properties and it doesn't show the columns of the logger at all like you had said which is exactly what you had just said that it wouldn't do if we used the syntax that you used. So now I'm confused and I'm not even sure if this has to do with dependency injection (Did a wrong logger get injected or what?) or if it has more to do with logging (which will be a video on my to-do list to watch now)... Could you please, especially in the event that this is due to a wrong logger being injected, explain why yours didn't work (at least the way I understood you saying that it should and would)? It seems like you're moving right along with the video here but maybe that's the whole point and you're about to explain. I'm just not sure and feeling lost now. I love all of your videos and how in-depth you are at explaining this stuff! I'm such a Virgo - I don't just google for snippets that work; I want to understand the code and HOW it works so your under-the-hood explanations are always so welcome in my world. I'm just lost and frustrated on this one as I've rewound and watched your prior discussions twice and what you were saying made perfect sense to me but then wham this output is nothing like what you had said I should expect and nothing like what my code-brain was expecting so please tell me what I'm missing! Thanks as always. You're in my top three youtubers and I can't get enough! (Your Dapper videos the best ever for the record!)
Serilog allows us to capture structured logs. However, our logging sink needs to support those structured logs. The console sink does not support structured logs. However, it still falls back to "normal" logs in those cases. When you then hook up Seq as a sink instead (or along with the Console), you will get your structured logging broken out. This video wasn't focused on Serilog and Seq, though. Rather, it was focused on using dependency injection to swap out your logger. If you want more depth on Serilog, Seq, and structured logging, check out this video: ruclips.net/video/_iryZxv8Rxw/видео.html
Mind-blowing explanation, every single second of this video is information information and information ⭐⭐⭐⭐⭐
Glad you liked it!
@@IAmTimCorey not only that, watching many of your videos related to C#. 👑One of a kind👑
Thanks for a great videos. This is really filled a lot of topics I missed on Dependency injection.
You are welcome.
Dear Tim, your video helps me a lot, you'r incredible!!
Happy to hear that!
You just saved my mind from a lot of frustration, thank you.
Glad I could help!
very well info on Scoped, that help me understand it better! Thank You!
You are welcome.
Best explanation on web!!!
Thank you!
Dependency Injection is amazing, but have problems with unit testing it with mocked objects. It would be amazing if you make a video about dependency injection's increased testability. Thanks for the C# content, like always!
Do you mean beyond what I covered here? ruclips.net/video/DwbYxP-etMY/видео.html
If so, please add it to the list on the suggestion site so others can vote on it as well: suggestions.iamtimcorey.com/
.
Excelent content about DI in net core, Thanks Tim for sharing this information.
You are welcome.
Best explanation and I just started to looking for DI, so I'm really happy that i run into the best one at first, it's not something happening all the time when you are Junior 😂. Simply the best, Tim! Thanks man!
You are welcome.
Whenever I want to understand something in .Net I ALWAYS go to your videos first! This is so well explained, thank you. I am hitting a bit of a wall now though - trying to implement DI in a .Net Core Class Library so I can do unit testing with mock classes. Hmm, no program.cs for starters. Any pointers please? And very Happy Christmas if you read this in time! All the best for 2025 Tim!
I'm glad my content has been helpful (and Merry Christmas to you). If you are working with a class library, you are creating the dependencies, but you are not able to actually set up dependency injection. That is because the class library is not the project that gets executed. A UI project gets executed and it can use a library. You can see an example of this in the Suggestion Site playlist here on RUclips. I use a class library there and it is used in dependency injection.
@@IAmTimCorey Many thanks Tim! I appreciate your explanation. FWIW I'm still working out how I am going to test the class library that I am writing (sorry I didn't make that clear that the library is mine). I'm finding more clues in all your great content as I go! :) The client of the class library is a large, old VB6 application - the class library I am coding is one of the steps towards migrating it from VB6 to .Net. It'll be worth it in the end haha! :)
You can test the class library with something like XUnit. It won't need to implement dependency injection because you will do that manually. If a class needs logger and data access dependencies, you would probably give it mocked versions of both since you are testing the specific unit, not the associated dependencies.
@@IAmTimCorey Thank you very much Tim. It's much appreciated! Yes, mocking the classes that perform the external I/O are working for me.
I am looking for dependency Injection in WPF that's ll be great
Thanks for the videos by the way. SO much to learn from
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/
Trying to convert a Windows Forms app to .NET Core. Changing to use DI as well. Couple of questions. If you have lots of services that a process uses do you need to create a constructor that has many parameter's? Or is there a way inside the component to be able to ask for the service when/if needed?
I had the same question
You need to provide them through the constructor. That's one of the benefits of dependency injection - you declare your dependencies up front instead of burying them in the code. By putting them all up front, you may have a dozen or more dependencies. That seems like a lot in the constructor, but that is just exposing what you are actually doing in the code. If you think that is too many dependencies, you need to clean up your code to not depend on as many things. Reducing your code complexity will be a big one.
@@IAmTimCorey Do you have an example for that?
What is being said at 5:06, "Can still use ada Config"?
EditorConfig.
I recently ran into the Singleton vs. Transient use for a project I started with Tim's recent Open API video where Singletons are used for the database access. But the tutorial I followed about Bearer Tokens and Refresh Tokens used Transients, and I had to look up the difference. Great video showing the difference and more info on DI.
Thanks!
How would you go about creating a multi-tenant .Net 6 MVC website with single code base/separate database per tenant, where most users will have access to a single tenant but some users will have access to multiple tenants? I want to use the same host name for all tenants in the event I need to use 3rd party controls that cost extra for additional hosts.
How does the server know when to release memory for the scoped dependencies? My understanding is that http is stateless. Is there a http communication to the server when a tab or browser window is closed?
if i wanted to preload a singleton (eg load some info from DB one time on first access) how do i achieve that with DI?
Great video! A suggestion would be to use concrete, practical names for folders and classes, rather than just "Logic" and "DemoLogic". Will help the viewer understand a lot better IMO
Is it possible to inject a dependency into a class without being forced to use the constructor? Is there a handy way similar to @inject that exist for classes not linked to a view?
Hi, just enlisted to your .Net intro course. looking forward to it after watching this video and the one on console applications with dependency injection.
I'm still wondering though about the following: with a .Net template I kind of get it. Every class can get access to the services container and request a service. Good for decoupling. But with your video on the console I got kind of confused. When I instantiate an object from let's say main, that object does not have access to services, right? not even if the console has set up a host.
my guess is that when you have template code like a Web API project, then the 'usecontrollers' thing in main takes care of making sure that all controllers get access to the host.
Does your dependency injection course go deeper into this? because for me it's now still 'magic' to see that the classes inside a WebAPI or MVC templated project do have access to the services container, while in the console version I still have to pass the host. (or I'm doing it wrong, that's also very possible)
anyway, the question is does your dependency injection course go deeper into how the classes get access to the host/services?
Another fantasic job!
Thanks!
35:07 How would you use this .NET Core structured Logging in combination with a StringBuilder? Let's say we have a List and want to display the IDs of all objects where a specific property is false for example. In this case I currently have a StringBuilder, iterate through the List, append to the builder whenever a condition is true (currently with append() and string-interpolation), and then write the result into the log file just once. Should I stay with that approach or rather explicitly call logger.LogWarning() or logger.LogDebug() for every affected object?
It depends. If you just want a string and don't want to filter or query on any of the data in that string, StringBuilder is fine. Otherwise, you should consider another route. You could convert the list to JSON and pass that in as a parameter of your log statement. Or you could log each line.
Thanks a lot for this valuable explanaiton. in case you have a new class, also, you will create an interface to it to register it, so, the place you want to consume it, you have to change the interface injection to the new interface, please correct me if I'm wrong. Also, I have inheritance "Abstract Class" with some common implementation for subclasses, using DI with inheritance is impossible, because they are different concepts. I tried it a lot, I didn't succeed. Appreciate if you correct me if I'm wrong. Thanks
So if I have the service in one project and the "consumer" in another, I necessarily need a third project, to put the interface in, and have both of the first two projects referecing it, right ? Just thinking where to put the interface, when organizing projects.
You could. That is the typical way of doing it.
My basic project to save Xlsx ko Xlsm works fine in my computer but it shows error and crashes at "saves as" line in others computer.
I used Ms excel interop for it.
What do u think would be a reason for error?
I was able to pin point error upto "save as" Line. But I don't know how I can resolve the issue.
My. Computer has 2019 office and all. Computer I tested had older version.
That's probably the issue. Excel Interop uses the version of Excel installed on the computer. That's the downside of using a library like that - you need to have Excel installed in order for it to work.
Hi! I'm following this example in as a Blazor Web App .net8 template in vstudio 2022 17.10.5 with Server render mode (per page/component). I can't get the AddScoped to work, as it always behaves like Transient. Singleton and Transient work as expected but Scoped always instantiates a new object every time. What's the diference?
**edit:** `@rendermode @(new InteractiveServerRenderMode(prerender: false))` makes it behave like expected but not sure why?
Thank you❤!! Tim!! I have watched everything for di in youtube and in your site. I am just stacked in a specific situation.
1. Should i avoid static methods and use singleton instead?
2. In which case i i need to use singleton and in which transient? I will give you an example on this. I have a class that includes only one method. No variables just one method called GetCustomers(). In this method i making a sql server query for get and return customers. What is the best approach for this class? Singleton, static method or transient??
There are reasons for static and reasons for singletons. I have videos covering those topics. As for your specific situation, it depends. If the method opens a connection, makes the call, and closes the connection (it is self-contained), then it is probably best as a singleton. If the method stores state of any kind, it might be better as a scoped or even transient.
@@IAmTimCorey Thank you Tim! what you mean . Please give me an example in which senario do you mean? Do you have videos in your site that covering difference between singleton and trasient and static method in depth? Please give me the link
Thanks Tim for the wonderful content, easy to understand
You are welcome.
Tim - would be great to see an updated video on how to set up DI for typical console apps in the .NET Core model (versus the old 2020 version).
I have web apps that use the same master data over a session. I've been using ProtectedBrowserSession for this, but would it be better to use Scoped DI for this data? What are the best ways to make the call as to approach on this?
I have the same question.
I'm not sure if I understand. You are asking about a console app but your example is a web app. I know that web apps are just console apps that have additional things on top, but that's a key distinction. I have a video here on RUclips that shows you how to add dependency injection in a console application. I also have videos showing you how to use dependency injection in a web app (this video included). As for saving your data over a session, I can't really give you a specific answer since there is a lot more questions to ask. However, in general you should use the web project type that best fits your needs. For example, Blazor Server is very good at having data over multiple calls (maintaining state). So is Blazor WebAssembly. MVC, Razor Pages, and API are not designed to do that but can. It also depends on your data. In general with a stateless website, you would want to remember the ID of the data locally and then request it again later rather than storing all of the data (that can be expensive and dangerous). Scoped DI probably isn't the right choice here, but I can't say for certain.
@@IAmTimCorey Sorry for the confusion. I have a couple of scenarios with .NET 6 and I'm trying to implement DI properly across both. We use a standard N-Tier solution structure, with BLL, DAL, Models, etc. projects being simple libraries that can be used with Console or Blazor as the "presentation" layer.
In Blazor/MVC apps, I'm able to set up DI using the builder.service and adding the [Inject] to the component's class file. However, I cannot figure out how to accomplish the same paradigm within the new .NET 6 Console app. The [Inject] annotations do not appear to work (or I have some misunderstandings of how it should work). I understand that we can just instantiate a class using its constructor to pass in dependencies, but I thought there was a way to use the [Inject] annotation to automatically pick up the particular service instance. Maybe I'm wrong on this.
Also, I understand that we want to instantiate the service once at startup, then pass it around to other solution project classes. Keep it clean and DRY.
In my case, I want to instantiate the ProtectedBrowserStorage at startup, then pass it to the BLL where I have a repo manage what goes into and out of the session state. But for whatever reason, the session instance is NULL even if passed to a constructor. I found this to be true with a repository instance as well. However, if I instantiate the session and repo and skip the builder.Service, I can pass them into other classes without issue.
Of course, in all of my attempts, I probably confused myself and got a wire crossed somewhere. Trying to wrap my head around it.
As you can see, I probably need a concise tutorial on how to get it to work the right way. Love your content! Keep it up.
This is an excellent video. Thanks.
You are welcome.
Great video, looking forward for more .NET > 6 !
Thanks!
You are Tim Corey! Thank you!
You are welcome.
I cannot wrap my head around any scenario where switching from logic to betterLogic is the case. Why not just change the classes? This comes from absence of experience tho. Is this when you have different projects which take data from project A to project B and project C has the interfaces?
Tim,
Thank you that make it understanle.
Q: in case i have Load Balancing for the web server, how exactlly it will affact the Singleton process?
Will the singelton instance be created once? or several times per each server instance?
Unfortunaterlly, I don't have the option to implament it and checking live by myself.
I just know that in the very old past, the answer was object instance per server instance.
Is it different in .net 6?
It would be once per server. In a load balancing situation, each instance only knows about itself. If only one of the server instances initialized the singleton, the rest wouldn't have it to use.
Really Excellent tutorial .. thanks for your effort
You are welcome.
Thank you for the video. What about Dependency Injection in .NET Core for 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/
Use SimpleInjektor
Another great tutorial. Looking for advice... I have a validator class using an interface, which more than one methods in the class will validate a single model(DTO/POCO). I planned on passing this model instance in the constructor, but am hitting issues with dependency injection and that it doesn't know about the POCO model class. How should I approach this? I prefer not to pass the model around to every method, was also hoping to avoid using a setter. Using constructor seemed to make sense so that the class has what it needs but doesn't seem to work with DI.
27:12 MAUI use scoped per window IIRC. Also, you can create a scope manually.. Nested scopes doesn't work unfortunately. I did some experiments.
hello tim thank you for the content just a suggestion when you explained the logger is good doing shorts on youtube about tips and tricks like that would be great thank 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/
Well done, Tim.
Thank you.
Thanks Tim👍
last week i was in a wishful thinking that your next topic will be something about IoC or DI then this 🤯
Awesome!
Tim, I wonder if parameters in constructors are supported. Your examples didn't use contructors with parameters :(
There are ways to do parameters in constructors, but it is really a hack. The ideal solution is to pass data in outside of the constructor.
you explained perfectly
Thank you!
Thank you amazing teaching and information.
You are very welcome.
Wow thanks ALOT.
This was just what I needed!
You're welcome!
@49:59 in Spring Boot we can easily get different beans for same interface just by mentioning the bean name or id during creation and wiring the bean with the same name to the target variable. Most of the things are better in Spring Boot except for few things like short hand syntaxes, build size and memory consumption which are better in .net.
Mentioning the bean name is the issue, though. Then you have coupling. That's something you need to be careful of. If you cannot swap out an element without changing your underlying code, you should probably rethink how you are doing dependency injection. Otherwise, you are basically creating distributed tight coupling.
Hm... you are also correct at your end, but in dotnet as well if you want to change a dependency you will to change in code i.e. in Program.cs file. In Spring Boot dependencies are created automagically using @Component or related stereotype annotations. These dependencies can be injected using constructor. This saves lots of developer's effort. In dotnet you will have to manually inject the dependency from Program.cs everytime you create the dependency class. In Spring Boot as well we can keep all the dependency at one java config file using @Bean annotation above methods returning bean. But it is not followed much for services and controllers because whole point is that we should be able to change the implementation of dependency by changing one line of code, which can still be done by removing @Component annotations from the previous dependency classes and adding in required ones.
thank you for your videos! great help!
You are welcome.
Thanks a lot. This video was on time.
You are welcome.
Now i understand how to inject a service in razor or .cs-code-behind file. But how to inject it in a class, in which a complex businesslogic is encapsulated for background work (located in an own project) ?
The same way. Your UI layer handles the dependency injection setup, regardless of what that UI layer is. In the case of a background service, the UI is the project that starts and stops the application.
@@IAmTimCorey Thanks for your answer and your great videos, but I haven't quite understood it yet:
Is the dependency passed to the backgroundjob via the constructor (constructor injection)?
Or can this dependency also be injected via a corresponding keyword similar to @inject? My problem is that I cannot use @inject in a normal cs class.
Hi Tim, I'm facing a problem in MySql. User 'a8b531_cmsp1' has exceeded the 'max_user_connections'. How can solve this?
It sounds like you are not properly closing your connections to the database at the end of the call. Make sure to close and dispose of the connection.
Why I can't have a model like a LIst as a scoped dependency injection so I can work with this list at different pages? It is not a database synced list, it just my current selection (probably not even a user at this time)
You technically can and for demo purposes (I just verified that it works), that would work, but it isn't the right solution for models. Especially since you usually want to overwrite the List instance, which is not something you should do with dependencies from DI. Models don't need to come from DI because they aren't dependencies, just data.
How does AddScoped works with cookies or session. If I have logged in I can open new tab and still stay logged in, will AddScoped return me same instance or create new instance? I suppose it will create new instance, if it does how to handle it?
AddScoped is on the server, so it doesn't know about cookies or anything else client-side. If you open a new tab, you get new instances of your classes that are marked as scoped. I'm not sure what you mean by "how to handle it". If you are asking how you stay logged in on different browser tabs, it depends on how your authentication system works. If you are using a bearer token, just store it in LocalStorage. Then, each tab can have access to it and you are set.
one probelm I ran into was having two concrete implementations that shared a interface that I needed in different situations. do you have a good solution to this issue?
Yes easy with multiple ways,
One way is reguster the concrete class for both and request the one cobcrete or both as you need.
Another yoy can reciwcw both objects and select the one you like with linq query
49:40
Yep, I addressed that in the video.
@@Holyflare it wasnt mwntioned how to allow both, he said change the interface and not doing this way.
Sometime the di depend on dynamic runtime and both can be requested.
The way I did it, do
Services.AddTransient();
Services.AddTransient();
Then in ctor used the Concrete signature to get the one you like
I did say you could do what you are suggesting. I also said you could put both in and then get an array of items. What you are doing is creating a hard dependency, which reduces the benefits of dependency injection. Why not just create two different interfaces, if you really want two different class instance types?
How to register dependency injection for a service that implements multiple interfaces?
Just register them like normal. It will just work. The key will be how to get those implementations. But for that, you need to know how to tell the system which one you want. You can either as for an IEnumerable of that interface and get all of the implementations or you can ask for one (and get the last one) or you need to have a way to differentiate the implementations.
@@IAmTimCorey I believe i was not able to describe the question clearly. I wanted to ask, suppose a service implements interface1 & interface2. Now how to register it in startup? If it implemented only interface1, in the startup I would only say services.AddSingleton()
But as i said, the service implemented 2 interface, how should I register it?
You could register it twice if you want to access only one interface at a time. Or you could register just the one interface and cast to the other interface when needed. Or you could create one super-interface that implemented both interface1 and interface2 and then use that to register the implementation.
How does .NET know that builder.Host.UseSerilog overrides the default logger. Does Serilog impliment a needed interface of that is the trigger? Great video!
When you set up Serilog in Program.cs, you put it in Dependency Injection. That overrides the default ILogger instance (Serilog implements ILogger).
Very nice explanation.
One thing I never heard was that an Interface needs a concrete class to implement it. I know this is not a vid on Interfaces but ... A brief explanation about programming to Interfaces and not classes would go a long way.
I do have a whole video on interfaces: ruclips.net/video/A7qwuFnyIpM/видео.html
This was seriously perfect, Thanks a lot.
You are welcome.
Is it really necessary to always extract an interface for every class you need for DI? Because the interface is just used for that one implementation. Is this not against the concept of YAGNI? I mean why not injecting the concrete class? Whats the disadvantage?
By using an interface, we can easily apply unit testing to our project. Interfaces allow us to easily mock dependencies.
Fantastic video! Now I need to go watch the full logging video. However, what if I wanted to inject into a class, which video covers that?
Inject logging or just any class? If you want to inject any class, just put that class in the constructor. If you want to inject a logger, put "Logger log" as a parameter in your constructor.
@@IAmTimCorey Thank you! I'm currently watching your appsettings.json video, and there is a small snippet in there where you show this! I've wasted hours and hours messing around with code trying to figure it out, you showed it in about 20 seconds. I love it!
Great video!
Thanks!
Excellent video. Thank you very much.
You are welcome.
Can u please please make a video for dependency injection in azure functions??
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/
Excellent timming
Thanks!
Nice Explanation
Thanks
You are welcome.
Hi Tim, In DI I always struggle when in some projects people use different ways - serviceCollection.AddScoped();
serviceCollection.AddScoped(sp => sp.GetRequiredService()); I am aware of the scopes but what is the difference between these two lines. When to use the first one or second one or what is the use of using both ? Please help. Thank you in advance.
Tim, if I am trying to make a list of fake employees to populate a demo application with, is it bad practice to add scoped dependency injection with a DemoDatabase class? (interfaced of course).
I want the user to have the ability to CRUD employees and have it reset when they leave the application. But I don't want that data to persist anywhere and I don't need an actual database - it is just so IRL employers can test my application in browser and assess its quality.
Thank you for your great tutorials and for taking your time to respond to commenters - I have seen you recently reply to people on videos from years ago! We appreciate the dedication!
That seems like a fine solution. As long as you understand the dangers (and you do), and you know that it is a demo and not something you should do for a "real" production app, go ahead and implement it.
Putting a semi-colon at the end of the line didn't automatically change the namespace to file-scoped. Am I missing something?
Are you using the latest update to VS2022?
@@IAmTimCorey VS 2022 17.2.3. the error I get is "Type or namespace definition, or end-of-file expected" at the top and bottom curly braces
would you please make a video explaining to us "the real benefits" of "struct/abstract/.... extra" or they are there abandoned and they have no real usage in our daily usage in programming
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/
In my console app, App calls a class which calls another class. Right now I am newing up the class so I can pass the logger. Is this a code smell?
It depends on the complexity of your app. Console apps can be simple enough that dependency injection isn't necessary. However, if they grow, having dependency injection can be a real benefit. In that case, you would want to let DI handle the instantiation.
Thank you Tim
You are welcome.
Really good tutorial, thanks.
You are welcome.
Hi Tim. Thank you for help that you give with videos. I would really like to see di in winforms.
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/
Hey Tim,
Thanks for the excellent explanation. I've watched your DI in WPF but I am still left with a lot of questions. Should I include all views and view models as dependencies? Can my view models have models as constructor arguments? Is it best to keep all constructor arguments of type interfaces?
Views? No. ViewModels? Yes. ViewModels are classes and they have dependencies that need to be fulfilled by the DI container. As for constructor arguments, technically you can but the ideal situation is to avoid that and pass the value in after instantiation.
@@IAmTimCorey I guess I thought views are registered because in your WPF video you had registered that main window and child forms. Was that only for demonstration purposes?
Thank you Tim. thank you for your efforts. I am not a .NET developer but interested to learn it. Anyway what makes me check your tutorial on dependency injection(DI) is that I've noticed that in many .NET tutorial they intensively use DI, nearly every class they add to the system they add it to DI.
For me I think using DI can be useful only in places where the class can be used in multiple places, such as the Logger you mentioned in your video. On the other hand adding all models to DI will make the code in the program complected with nearly no need for that as most of the classes will only be used once or tow times.
What do you think? is it practical to add all models to DI?
I don't add models to DI normally. Those don't create dependencies. However, all other classes get added to DI all the time. There are very few apps where I don't use DI. It allows for easier/better upgrades, less coupling, and easier testing. Here is a video on the Dependency Inversion Principle (the D in SOLID) that explains this concept better (DI is an implementation of this principle - they aren't the same, which I will explain in the video): ruclips.net/video/NnZZMkwI6KI/видео.html
How to you share exact needed tutorial whenever I need? You're amazing! Thank you for teaching!
I am glad it was so helpful.