Dependency Injection Updates in .NET - Keyed Implementations

  Рет қаралды 20,733

IAmTimCorey

IAmTimCorey

6 ай бұрын

Dependency Injection has some new features in .NET 8. Specifically, we can have keyed services, allowing us to have more than one implementation of an interface. Let's see how they work in this 10-minute training video.
Full Training Courses: IAmTimCorey.com
Source Code: leadmagnets.app/?Resource=DIU...
Mailing List: signup.iamtimcorey.com/

Пікірлер: 61
@TichShowers
@TichShowers 6 ай бұрын
I think a good use case is removing factory classes to essentially do the same. Instead of injecting the factory and calling a method that performs the switch case, you can just call for the correct injection.
@aimene_.
@aimene_. 4 ай бұрын
How could you call a specific class if the keyword is specified in the constructor parameters? I don't think this will replace the factory pattern..
@TichShowers
@TichShowers 4 ай бұрын
@@aimene_. Only factory classes which do service determination based on a single static key are going to be replaced. Like getting a filestreamvalidator based on file type. the interface can be the same, but the implementation really depends on the file type being validated. The use case isn't extremely common, but can be useful nonetheless.
@mrsajjad30
@mrsajjad30 6 ай бұрын
Thank you Mr. Tim Corey for taking your time and making it easier for us.
@IAmTimCorey
@IAmTimCorey 6 ай бұрын
You are welcome.
@Sander-Brilman
@Sander-Brilman 6 ай бұрын
Nice video. great you not only showed how the feature works but also the edge cases (such as blazor components) and how to do it propperly by not using magic strings but rather enums. quality content.
@IAmTimCorey
@IAmTimCorey 6 ай бұрын
Thank you!
@talkathiriify
@talkathiriify 5 ай бұрын
Mr.. Cory Your solutions always greate and excellent. Thank you so much for your time and efforts.
@IAmTimCorey
@IAmTimCorey 5 ай бұрын
You are welcome.
@TuanAnh-hc1nm
@TuanAnh-hc1nm 6 ай бұрын
This is a really useful feature, especially for testing. I used to spend hours with headaches on this
@IAmTimCorey
@IAmTimCorey 6 ай бұрын
I am glad it was helpful.
@manuelgamezz
@manuelgamezz 5 ай бұрын
Thanks Tim, It's an easy example to understand the new feature.
@IAmTimCorey
@IAmTimCorey 5 ай бұрын
You are welcome.
@codeme8016
@codeme8016 6 ай бұрын
Wonderful contents. Thanks for the update!
@IAmTimCorey
@IAmTimCorey 6 ай бұрын
You are welcome.
@waynehawkins654
@waynehawkins654 6 ай бұрын
Nice - thanks Tim.
@IAmTimCorey
@IAmTimCorey 6 ай бұрын
You are welcome.
@catalinmarianmursa7892
@catalinmarianmursa7892 6 ай бұрын
Great video!
@IAmTimCorey
@IAmTimCorey 6 ай бұрын
Thanks!
@BrentHollett
@BrentHollett 6 ай бұрын
Can the selection be specified at Runtime? We have similar services on the same interface for different versions of a platform that we're interfacing with, and we dont know which one we need until runtime.
@grantpeterson2524
@grantpeterson2524 2 ай бұрын
Thanks so much for this video! Very helpful. One thing I'm wondering is what is your recommended pattern for utilizing keyed "Options" would be? Maybe I'm just completely misusing `IOptions`, but when I try and add a keyed option using `IServiceCollection.Configure`, the `name` argument only allows a string, not an enum like I was hoping. What would your approach be? And are there any attributes I can utilize like with keyed service to ensure I'm injecting the correct `IOptions` directly? Thank you!
@FireIn8
@FireIn8 5 ай бұрын
Thanks!
@IAmTimCorey
@IAmTimCorey 5 ай бұрын
You are welcome.
@darylbeaumont8855
@darylbeaumont8855 6 ай бұрын
Great video, Tim! A more specific question on Blazor: is extracting the code into its own code-behind generally recommended most of the time? It feels as though you have more control in code-behind. I’ve not really used Blazor up until now, so I’m curious!
@IAmTimCorey
@IAmTimCorey 6 ай бұрын
It really depends on the amount of code you have in the code behind. I personally leave it on the page unless it gets larger. And then I evaluate if I'm doing too much on the page.
@darylbeaumont8855
@darylbeaumont8855 6 ай бұрын
@@IAmTimCorey Makes sense! Good advice! Thank you
@404-UsernameNotFound
@404-UsernameNotFound 6 ай бұрын
3:19 Is there an advantage to using the traditional constructor like you did vs the new primary constructor in .net8?
@seesharp81321
@seesharp81321 6 ай бұрын
Nick Chapsas has a video on that
@paulegan3783
@paulegan3783 6 ай бұрын
Thanks Tim. What's the benefit of this over just asking for an instance instead of the interface in the Demo class? For example for the constructor: public Demo(InformalMessages messages){} Isn't the whole idea of injecting interfaces to give the user of the class a choice of which instance to inject? (Sorry if that's a newbie question or I'm missing something obvious).
@jirinovotny9704
@jirinovotny9704 6 ай бұрын
The DI container in Tim's demo actually has two registered implementations for IInteractionMessages interface. The default behavior of the built-in DI container from Microsoft if you wrote your constructor like public Demo(IInteractionMessages messages){} is that it provides the last registered implementation which in this case was the "relaxed" implementation. You would always get the last one, in no way you could get the formal one unless you asked for IEnumerable in the constructor or wrote a factory class. The new feature of the DI container in .NET 8 is that you may pick a specific implementation in the constructor itself by using the key you used for registration. So you do not need a factory class or factory method which you needed in previous versions to achieve the same behavior.
@paulegan3783
@paulegan3783 6 ай бұрын
@@jirinovotny9704 Ah ok, that's helpful thanks 👍
@jirinovotny9704
@jirinovotny9704 6 ай бұрын
I've just noticed you were asking for the specific implementation class in your constructor. It is possible to ask for specific implementation but you would have to have it registered in the first place (which Tim didn't do), otherwise you would get a runtime exception. Asking for an implementation class also defeats the purpose of IoC and the decoupling of abstraction and implementation. You would end up in having tight coupling between your Demo class and InformalMessages class which is not the best practice.
@paulegan3783
@paulegan3783 6 ай бұрын
@@jirinovotny9704 Yeah I initially interpreted the key as creating tight coupling just like asking for an implementation class. I'm gathering this is not the case although it's not clicked why yet for me. I think I need to learn a bit more about the Microsoft DI container and how it works. Thanks for your responses, much appreciated!
@MiningForPies
@MiningForPies 5 ай бұрын
@@paulegan3783you can of course ignore the attribute when manually constructing objects, say when setting up unit tests.
@aimene_.
@aimene_. 4 ай бұрын
If i understand, it will not replace the factory pattern. For example if we want to implement a specific class depending on the configuration in appsettings.json ?
@IAmTimCorey
@IAmTimCorey 4 ай бұрын
You could do that now with dependency injection (no need for an additional factory pattern). Just have a method that checks the settings file and then adds the appropriate dependency to DI at startup.
@johnytodorov3129
@johnytodorov3129 6 ай бұрын
Hello Tim, I want to ask do you know how this keyed implementations, will work with Unit Tests, I mean how you can mock object of Interface but with specific "Key" ?
@IAmTimCorey
@IAmTimCorey 5 ай бұрын
Create a keyed mock that you pass into your DI container.
@clebersondot-net
@clebersondot-net 6 ай бұрын
I liked this way to injected with Blazor. But and the other way using "normal" singleton without keyed? We doens't need using anymore?
@jirinovotny9704
@jirinovotny9704 6 ай бұрын
You still can use "unkeyed" registrations unless you have more implementations for an interface that you want to switch between. Having a keyed registration in the DI container when there is just one implementation doesn't make much sense.
@peng943
@peng943 3 ай бұрын
Could you please help answer what is the benefit of this comparing to inject multiple interface implementations? Even the key is a Enum, it still looks like magic string smell in a certain way.
@IAmTimCorey
@IAmTimCorey 2 ай бұрын
It reduces the need for unnecessary interfaces. Imagine you have an IDatabase interface. Then imagine you have implementations for SQL and SQLite. Now imagine your application actually uses both, not just one. You use SQLite for client-side storage in your WPF app and your SQL for server-side storage when your system is online. You could create ISql and an ISqlite interfaces that inherits from IDatabase so that you could add both to dependency injection. Or you could make them keyed services.
@DagothThorus
@DagothThorus 5 ай бұрын
Behind the counter... I see what you did there :)
@IAmTimCorey
@IAmTimCorey 5 ай бұрын
😉
5 ай бұрын
In 3:18 what is the shortcut for removing the curly braces from namespace?
@IAmTimCorey
@IAmTimCorey 5 ай бұрын
Just put a semicolon at the end of the namespace declaration.
@saulasheriffdeenolamilekan4540
@saulasheriffdeenolamilekan4540 6 ай бұрын
nice...
@IAmTimCorey
@IAmTimCorey 6 ай бұрын
Thanks.
@olegsuprun7590
@olegsuprun7590 6 ай бұрын
I don't see a big use case for this. First of all we already have a way to do it via registering a delegate in the IOC that constructed a correct service based on some parameter. Second issue: the only time we need to have multiple implementations registered is when we need to decide at RUNTIME what implementation we need to use. By injecting the concrete service with an attribute we are neglecting all the benefits of flexible runtime behavior.
@IAmTimCorey
@IAmTimCorey 5 ай бұрын
The statement "the only time...(is) at runtime" makes me twitch. Whenever you catch yourself saying "always" or "never" or their equivalents, you are almost certainly wrong (even in that I didn't make it absolute because there are probably edge cases). For example, you may have two services that do something similar like texting a confirmation vs emailing. In certain circumstances, you might want to do both (and the interface would be the same so you could). In other cases, you might want to only do one or the other. You might want to email a receipt (but not text the whole receipt), you might want to text a confirmation code, and you might want to both email and text delivery information. That would be a design-time decision, not necessarily a runtime decision. There are lots of people that were using the existing functionality of multiple implementations for one interface and then choosing the one specific one they wanted after getting the list (but still at design time). This change just makes it easier for them. No, it isn't going to be an everyday solution, but it is a solution that will make some code much cleaner.
@alessandrocaliaro9808
@alessandrocaliaro9808 5 ай бұрын
Hi. Does this work also for MAUI?
@IAmTimCorey
@IAmTimCorey 5 ай бұрын
Yes. MAUI now uses the same .NET so the features all work.
@sakenda
@sakenda 6 ай бұрын
You could have done the same in the code section with the inject attribute
@IAmTimCorey
@IAmTimCorey 6 ай бұрын
Keyed implementations aren't supported as injected values in Blazor yet. Not unless you use the code behind in a separate file.
@chrisl8292
@chrisl8292 6 ай бұрын
4:10 - it's pronounced E - NUM. Num as in number. In 25 yrs of being a dev, first time I've EVER heard someone call it a e noom. 😮
@IAmTimCorey
@IAmTimCorey 6 ай бұрын
Don't start trying to gatekeep pronunciations. Those vary per region. There are a lot more important things to worry about.
@ashpro5339
@ashpro5339 6 ай бұрын
I think the tutorial is not completed...
@allthecommonsense
@allthecommonsense 6 ай бұрын
Why
@daver1024
@daver1024 6 ай бұрын
Where is "Messages" displayed?
@IAmTimCorey
@IAmTimCorey 5 ай бұрын
The point of the tutorial wasn't to create a working application. The point was to show how to get keyed dependencies out of dependency injection. I did that. I just didn't show how to then use those dependencies. That was outside the scope of the tutorial.
@jeffreystines7833
@jeffreystines7833 5 ай бұрын
Instead of using an enums for the key could you use nameof()?
.NET 8 Adds Shuffle to Random for Arrays and Spans
3:46
IAmTimCorey
Рет қаралды 7 М.
Bash Scripting on Linux (The Complete Guide) Class 02 - Hello World
17:24
How To Choose Ramen Date Night 🍜
00:58
Jojo Sim
Рет қаралды 61 МЛН
Тяжелые будни жены
00:46
К-Media
Рет қаралды 4,6 МЛН
didn't want to let me in #tiktok
00:20
Анастасия Тарасова
Рет қаралды 12 МЛН
Worker Services in .NET Core 3.0 - The New Way to Create Services
47:09
Background Jobs in ASP.NET Core
18:35
IAmTimCorey
Рет қаралды 43 М.
How IDisposable and Using Statements Work Together in C#
10:01
IAmTimCorey
Рет қаралды 28 М.
Mastering Dependency Injection In Golang
14:29
Anthony GG
Рет қаралды 41 М.
Dependency Injection, The Best Pattern
13:16
CodeAesthetic
Рет қаралды 722 М.
Concurrent Hosted Service in .NET 8 | .NET Conf 2023
31:12
Global Error Handling in C# Minimal APIs
13:59
IAmTimCorey
Рет қаралды 13 М.
How To Choose Ramen Date Night 🍜
00:58
Jojo Sim
Рет қаралды 61 МЛН