As your application grows, you're going to have more dependencies,
more classes, more services, more view models, more interfaces.
And what you need to do is easily resolve those dependencies and built into.net.
And .NET Maui is dependency injection, which gives you the architecture
pattern of inversion of control, and specifically constructor injection.
So, what I'm going to do today is break down everything that
you need to know about all those fancy words that I just said.
So you can be more productive when building your Dyna Maui applications.
So tonight.
Hey everyone.
I'm James and I'm back.
And today I'm going to be talking about a really near and dear topic to
my heart because it's one that I've thought forever, which is dependency,
injection, and specifically constructor injection, and inversion of control
and all of these things, uh, that are all fancy words, just to say.
Well, I have this thing and I want to resolve it or get an instance of it later,
you know, knew it up to these things.
Now I had a video specifically around Xamarin forms and dependency injection.
And many of you were like, James, that's not a dependency injection.
That's a dependencies service.
Yeah, yeah, yeah.
I get it.
But think of it like this, right.
As our application grows, we have pages.
We have view models.
We have services, we have interfaces.
We have a whole bunch of different things and we need to resolve those dependencies.
And you think of it like this as like a dependency is one, one object.
Depends on another object.
Now, if you're coming from the asp.net core world, you're gonna be
like James dependency, injection.
It's built in.
I know everything.
Yes.
And it now is with Don ML, which is really, really cool.
Now there's really two parts.
There's the dependency injection and there's that, you know,
um, a constructor injection.
So I think of like, this is dependency, injection, DEI,
and IOC inversion of control.
They're very much the same thing, but it's a way of resolving thing.
But again, a dependency is an object that depends on another object.
So let's look at an example.
So you have a page.
And what does the page have?
It has a view model that is the dependency.
Now in practical terms, you could just new, up a new view model.
Now that's fine and dandy, not a big deal, but what if you want to, you know, have.
Uh, dependency of that view model, for example, maybe that view model
takes in an eye database service.
All right.
Well, new up a new database service and you're like, well, what if that
database service needs an SQL service?
And what if you also need an eye connectivity service?
Uh, you're like, oh, like what is going on here?
Like I have this huge dependency graph basically.
And I think I'm most terms when we're building apps, uh, with .NET Maui or
even, you know, a windows applications or, or, or web applications usually
have a UI, some code that's in the code behind that thing uses services.
I always see it as like three layers deep right.
Page view model services, and the services could be anything.
It could be a database.
It could be, you know, uh, one of the essential API APIs, like getting
access to a file picker or kind of.
So that is what we need to do.
Now in .NET Maui, there is a dependency service that's built in.
That's different than the old one that is still there, but actually
it's a built in service provider.
That is the same one that's using ASP on that core.
So if you're used to dependent, you know, Newing up and registering dependencies,
this is going to feel very familiar.
Now there are specifically two types of dependencies that you can have a single.
And a Singleton, um, is something that is sort of like you think of it
like global almost it's it's a one instance is a single instance, a of it
and a Singleton, uh, essentially says, Hey, if, if you've created it once
and you want to get it again later, then go ahead and retrieve that same.
And then you have a transient and a transient is the opposite of
a single-tenant transient is a single instance every single time.
So every single time you new up a new one.
So based on what your application and where you're using these services, you're
either going to want a Singleton or a transient, uh, Now you can actually
use this built in service provider, um, with, or without the app shell.
But when you use it with app shell, which is part of the default template,
I have tons of videos on my YouTube, all about which you should totally use.
Cause it's amazing.
And it's in the default template, um, because you do URI navigation and all
this other stuff, but it also includes.
Constructor injection and automatic dependency resolution.
And this is the thing that developers have really, really wanted when
it came to client development.
And this is what this brings and yes, there's been frameworks that have
done this for a while, but now it's built in to the box and now I'm all
in and yes, everybody should use it.
And it's absolutely amazing.
So let's go ahead and take a look at some.
All right.
So let's go ahead and take a look at this application.
It's very simple.
It's very similar to the file new project, but it has a button that I
can click and it increments by 10.
That's pretty nice.
And also a navigate over here and I can check the.
And it says, yes, I have internet because I currently, till I have internet.
Now, if we look at this application, this is file new project, but I've
added some MVVM goodness to it.
If you don't know about MVVM model view, view, model a
sort of a way of abstracting, your code separating concerns.
And I have a video that'll put up over.
Now, this is just a shell, which I highly recommend you shall.
It's the file new project.
It has a lot of nice things and you'll see why in this video, but
there's just news up the main page on.
If we look at the main page, we can see that it has some labels that
has, um, this, this label here that's binding to count with a string format.
It has a button that says, click me to increase the count
and another one to navigate.
If we look at that code behind it's quite straight forward, there's not a lot.
It just news up a new main view.
And then main view model over here is very, very simple.
It's using the community toolkit for.net and MVVM.
So if you don't know about that as these awesome attributes to do source generation
of all that MVVM stuff, uh, which is rad.
I have a video which I'll put up there and down there too.
Um, but I have a simple count increment.
And then this I command to navigate, and that goes to the detail page.
And I've also registered this detail page with my routing
system inside of the app shell.
So this says for the string detail page, create a new detail page.
So that is why here I can say name of detail page and I'll
know to navigate to that page.
Now that detailed page is also straight, straight forward.
It has a button, it has a view model.
And that view model over here is a little bit more complex.
It still fits on one screen, which is nice.
Uh, it has an eye connectivity service, which is coming in from Microsoft
Maui networking, uh, and it just gets the current instance of it.
Then down here, what this is doing is it says, has internet.
Um, and then it just displays it as internet or not, which.
So let's talk about the dependencies here.
We have the view models, and we also can see that we have this
connectivity, um, thing as well.
So this, this also is a dependency because if I was doing unit testing, I would
want to mock out this icon activity.
So let's go into our Maui program.
And this builder is very similar to the asp.net core, uh, kind of host builder.
So here on the builder itself, I can say builder.services.
And this gives me an eye service collection to register my dependencies
with the Maui application.
So I can add a Singleton or a transient.
So when we think about this, the main page, the main view amount of
there's only one of them, which means that's a good indicator that I can
register anything as a Singleton.
So I'm going to say, all right, let's do our main view model here.
And we've registered that as the Singleton.
Now the detail page that one's a little bit different, right?
We're only actually navigating and creating a new page
and it might be different.
Maybe it's different data.
So I'd probably want to create a new one every time.
So I'll do builder.services dot, add transient.
Like I talked about I'll do detail view model.
Now, this is kind of cool because you can register your dependency chain here.
Now, if you want to get them, lot's a little bit tricky because we want to
actually access and get rid of this new creation over and over again.
So surprisingly, um, when you build it up, that's when it's going to do the
registration, it's going to do stuff.
So if I was to say, VAR app equals build their.app and this return, the.
Here we can look at that app and we can see it also has a
services, um, service provider.
And here I can actually say, get service, there's get service, get
services and things like that.
So I can get those back, uh, automatically.
So for example, if I say, get service, main view model is going to access.
And get that Singleton back.
If I did detail view model, it would create a new one.
Every single time.
I called that.
Now this is a little bit of bummer because, you know, I have my Maui
app.services over here and you know, it's not actually a Maui app.
Uh, Services.
It's not a static.
So if I needed to expose this, I'd have to create it as a static.
Save this I service provider around.
That just seems like not the greatest of practices.
So there's a nifty way of getting access to these.
And I have this service provider and I'll give all the credit to
David or now, because I stole this from his, whether 21 app.
So we take a look here.
This is my service helper and the service helper gives me access to.
The service providers.
Okay.
This is actually really neat.
So this is something like I said, like I stole from David or now, but what happens
here is that each lower level platform has access to the eye service providers.
So we can see here, we have windows, Android, and iOS as well.
So if we toggle this to Android, we can see that that lights up.
And it created this very simple static method to get the service
off of the current services that is there, which is really, really cool.
So if we talk about that back and forth, we see that light up.
Now, now what we want to do is use this and call get service.
And I know what you're saying, James you're like James and my goodness.
This looks exactly like the dependency service that you did a video on.
No, no, no.
It's different.
Trust me on this.
You got to trust me.
There's already singletons and transients.
That's different.
So, so bear with me.
Let's go into the main here and let's call into that service helper, not
server, but service, service, helper dot.
Okay.
Now when we do that, we're going to bring in that nice little helper.
And I'm going to call get service of main view model.
Perfect.
Perfectly there.
All right.
Now what I can do is I can also come into the detail page.
Let me put a break point here.
Detail view model.
There we go.
Awesome.
And let's just go ahead and add a break point here.
Uh, that using statement and let's debug it again.
Now, here we go.
Make sure I actually write the correct code.
So when we do this and make this call, right, what's going to happen is that
the main view model will only have one instance and that detailed view
model will have a new one every time.
So now when I come over here and I say, click, click, click, click, click.
That's good.
Navigate.
Check this out.
We're requesting our detailed view.
Skip down and sure enough here is my check internet command and
all this goodness that I have all registered a hundred percent.
So that is good.
Now in this approach, though, you still aren't doing any constructor injection.
You're not doing anything special, but it does come with a really
cool caveat, which is that you are actually able to register dependency.
Of dependencies through constructor injection.
Now, what that means is if I go into this detail view model, instead of accessing
connectivity dot current, I could pass in and I connectivity of connectivity.
And instead of grabbing that Singleton, we can just set it here.
So this is really, really fascinating because so far.
We've just looked at registering simple services and then getting them.
But now what we're going to do is resolve dependencies of dependencies.
So let's check this out.
So if we go back into our Maui program, we're going to have to register that.
So I'm going to say builder dot and you know, that kind of activity service you've
got to decide, like, is it a single tenor, a transient, well, it's already static.
So you know what?
Let's just register it.
Uh, as a single 10, um, add Singleton, I'm going to say I kinda activity.
And here you can actually pass in connectivity dot current in there, and
that's going to register connectivity to our current as icon activity.
So you actually have this way of when you're doing interfaces of
passing in, you know, the contract and then the implementation of what
would be there, which is quite nice.
So now if we run this again, when we create that detailed view model, We'll
not only get the detailed view model, but if I go and add a break point here,
the connectivity service will also be passed in, which is like really cool.
Right.
So here I'll just navigate around boom.
And sure enough, there is my connectivity implementation passed in 100% automatic.
All right.
So that is really, really neat already.
Okay.
So.
I love that.
I just simply love everything about that.
And if you want to take it a step further, you could, for example, actually
register your pages with the service too.
Right?
So now we're kind of coming in here and we're calling the service model, but it
sure would be great if we didn't have to.
Now, this is where things like.
Tricky.
Okay.
Because if you are not using shell, how are you supposed to
tell the app when you create a new page to go register that stuff?
It's quite tricky.
To be honest with you, you can create a new constructor and then you
could pass in the objects and then get the services from all of them.
But it's really not the best approach.
That is why I love.
Shell for doing this.
Okay.
Because it handles all of the complexity automatically for you.
So here's what we want to do.
We actually want to pass in the view model.
All right.
And here, I'm going to get rid of this call VM.
Beautiful.
I'm now going to go into the detail page and do the same exact thing.
So VM perfect.
I'm gonna type in VM here.
Awesome.
All right.
So now we're passing in our dependency of the view model into this.
Now we need to do, as you guessed it, I'm going to come in and say
builder.services dot add Singleton.
I'm going to add the main page.
All right.
And I'm gonna do builder.services dot add transient of detail page.
So now we have not only our pages, but our view models and our connectivity service,
all registered and everything is being passed in via constructor right here.
Now, in fact, what I love about this model is that if you look at the
app over here, the app actually news up a new app shell inside of here.
So this is super good.
And this handles everything for you automatically.
If you weren't using using shell.
Dependency inject the main page in here too.
Like if you wanted to, you could say, you know, main page page, and then, you
know, replaces as, as page for example.
Um, but since we're using shell, we don't need to do that, which is good.
That's really cool.
So now let's check this out because when I run this, I'm going to note that here on
my detail, on my detailed view model, when I navigate to that page, I opened this up.
We're going to see that.
All of our break points lineup.
Okay.
So we have our click counter, which that view model is coming in.
I'm going to navigate here.
Our detailed view model gets created passing in the connectivity because
it's been automatically resolved.
And hit, continue and note here that our detailed view model
has automatically been created.
It's going to be assigned to our binding context all by navigating 100%.
So when you call in your code app, shell, current go-to async,
that is going to notify dynamic.
That, Hey, it is go time.
It is time to go see what is registered.
And if my page is registered, I can automatically start going and finding
the dependencies of those pages.
All right, now I ran down a lot.
I hope that you rewatch this video about 58,000 times, but I
hope that I helped explain why dependency, injection, constructor,
injection, inversion of control.
All those things are so amazing in dynamic.
Especially when using shell.
And this is really cool because the more dependencies line up it automatically
handles all those things for you.
A great example is the podcast application.
I've talked about a lot here, but the dinette podcast application,
I'll put a link down below this.
We'll actually use native services that have been registered to on iOS
and Android to do audio playback.
And it does all the pages, all the new moms.
I additionally, if you're looking to get started building and learning
Don and Maui, I have an entire workshop that's over on the dotnet
presentations, there's a bunch of workshops there it's a six part course.
You can file new up to building and deploying all happy.
You're going to learn about navigation passing parameters with shell, and of
course, doing dependency injection and doing all these really cool services.
So I hope that.
You know, get a full grasp of what's going on here, why it's
so unbelievably flipping cool.
And that way you should totally be using shell and dependency injection
all the way down from top to bottom, I'll put all the links in the show notes
below and links to other things like MVVM community toolkit and so much.
I really hope you enjoyed this video.
And if you made it this far, give it a thumbs up.
I'm serious.
That super-duper helps the channel.
Honestly, I want to reach more people, share the down Moe, Guinness with
everybody, and there's a share button.
You can share it on anywhere you put on LinkedIn, you put it on Twitter,
you put it anywhere, but I'll all the places just share with people.
YouTube algorithm loves that stuff.
And finally, don't forget to hit and smash that subscribe button like
every single YouTube has told you forever and ring that notification.
So you get new videos.
When I put them out here on my channel.
Super appreciate it.
Leave comments below.
I'll totally get to them.
And I hope to check you out soon.