Today, we're going to take a look at the built-in support for dependency injection
or dependency services in Xamarin forms.
This gives you the ability to tap into native functionality easily
from your shared code, or just create really reusable interfaces for your
application that are really testable.
So tune in.
Hi everyone.
I'm James Monson, Magna.
I'm back with another Xamarin one-on-one video.
If you haven't checked out the series or right up there, I'll put
it over there and a little card.
I've been building out an application from scratch, showing you how to
incorporate beautiful, awesome features of Xamarin forms to native
iOS and Android applications.
All built with C-sharp and visual studio.
We've come quite a long way in our application.
We've done a lot of backend services, databases, theming, and a lot more.
And today we're talking about dependency, injection or dependence.
I see services with Xamarin forms.
Luckily for us, Xamarin forms has this built in out of the box and it's really,
really fast and it's, uh, it's compiled up and it's got some really nice ways
of sort of abstracting your code.
Now if you're new to C-sharp or want to know what dependency injection is, what it
does is it enables you to use a powerful feature of C-sharp called interfaces.
And an interface is just a definition of what.
Methods or properties are going to be inside of a class.
So for example, we have the coffee service, and right now it's a
bunch of just static methods that we can randomly call, but we may
want it to be a specific interface.
So we could swap out a database with another database or a web call.
So we create an interface and an interface we could describe methods or properties.
So get a coffee at a coffee, remove a property.
And what's nice here is that with an interface, if multiple classes implement
that interface, we know exactly what is going to be in a definition.
And this again is really nice.
If we do want to swap out our database with a different database,
want to make a web request, we want to use something else.
Um, it's a really nice way of creating reusable, um, um,
interfaces or definitions of what these classes are going to be.
The side effect here is that it also enables you to
create sort of testable code.
You can test.
These interface methods and properties inside of your unit test
without having to construct objects.
And you can use a bunch of different test frameworks that are out
there, like an unit and X unit and interfaces are very popular.
In fact, we've done at Maui.
All of the controls are interfaces too.
So they're, they're kind of all in that sort of awesomeness,
um, which is kind of cool.
Also, it enables you to create a way of tapping into native functionality.
So for example, you may want to have like a toast service.
So something like pops up a little notification, which
we'll implement here together.
Um, well that doesn't exist in shared code like that copy service has shared
code, but how do I reach Android or iOS or windows or back functionality,
you can create an interface and then implement it on each platform.
And like I said, the nice thing is Xamarin forms has this all built in.
So let's get started.
Okay.
The first thing here is actually have a coffee service.
Like I mentioned earlier, we have a few coffee services, but you
know, the one that we're going to create today is this coffee service.
Um, and it's going to have a few methods such as an in it
and add coffee, remove coffee.
It also has a get coffee, things like that.
Now, technically this.
In it method doesn't need to be on the interface because it's not
even public interfaces are really just going to describe public
facing methods that we want.
So to get started here, we're actually going to use visual
studio to generate the interface.
So I'm just going to go ahead and remove these statics because without that visual
studio won't know how to refactor it.
Now I'm going to tap on this coffee service.
Right click and say, quick actions and refactorings, and we can see over here
extract interfaces right here for us.
That wouldn't be there if everything was static, but since it's just a normal
class, we can extract that interface here.
It's going to ask us what we want.
So we're going to select all which is good.
I coffee service.
That sounds about right.
And let's see, add coffee, get coffee, gift coffee with an ENT and remove coffee.
Notice that it did find only our public methods that are in here.
And that's perfect.
So let's go ahead and do that.
It's going to create a new file called I coffee service.
Yes.
All right.
Let's take a look at I coffee service.
There it is.
So there's I coffee service.
We don't have to do anything it's created at all for us.
We could have created this manually if we wanted to too, but
here's our eye coffee service.
Here it has task.
Add coffee.
So name roaster, get coffee, get coffee, remove coffee.
We go back into our coffee service.
Actually, nothing here has changed.
All it did was implement I coffee service.
Now, if I go and add another method over here, like task, do something.
All right.
I can go back into my coffee service.
Uh, we will see that now we get a red squiggly and it will tell us that
we want to implement that interface.
And then it will implement it here for us.
Now we're not going to do that because we don't have that.
But showing you that when you add new interfaces, you need to implement those
with C-sharp nine, you can actually do default, um, implementations,
which is kind of cool too.
Um, just a nice feature.
Now the cool part here is that actually our internet service coffee
actually implements the same stuff as I get has, you know, add coffee.
It has removed coffee.
So we could actually implement that interface here too.
And we could then create reusable sort of ways of of saying
what coffee service do I want?
Well, just stick with the one, keep assemble.
We now have our coffee service.
Now there's two ways of telling Xamarin forms that for this interface, I
would like to use this coffee service.
What we do is on top of the namespace.
So we can do an assembly dependency over here and bring in Xamarin forms, poop,
and the dependency shows us what type.
Do we want to bring in, so here we'll say type of, and we'll say coffee service.
So we're saying create a dependency for the dependency service that's
built in with the coffee service.
Now, what this does is this sort of assembly attribute will automatically
detect any interfaces that this class implements and enable us to get one.
Basically a coffee service globally back just from that single interface,
we could also get just that class back if we want to, because it
will also register it there for us.
Now, I also want to mention that some people don't like these
kinds of assembly exports, you can actually put them anywhere.
So if you wanted to put them in your assembly info with all of your
export fonts, you could do that too.
Some people like to do this inside of the code when the app starts so
they can see all their dependencies.
So instead of putting that, you know, dependency there, we can come in here and
we can actually say dependency service.
Dot and notice that there is a, get a register, a registered
Singleton and a resolve.
So there's these three different ones that are in here.
So register enables us to register any class.
A Singleton is obviously a Singleton, so you only get one instance of it
back and you can resolve those back, the resolve Singleton or resolve
and register single tender, newer.
But what I can do here is I can say I coffee service here.
As my type that I want to register.
And then here, um, oh, that's it actually, it's just AI coffee
service or just coffee service.
And that we'll go ahead and do it.
So does this register it all automatically?
So very, very similar, uh, there, um, notice that there's a single
class, but here also implementation.
So that's actually probably what I need to do, which is I coffee
service and then coffee service.
Copy, sir, this, there we go.
So in this case, I had the ability to register just the
class or the implementation and the actual coffee service there.
So it's sort of up to you.
I personally prefer just to keep them right in line right here with this nice
assembly export and go to town there.
So now let's say we want to get access to this.
Well, that's actually pretty easy to do.
So if we go into our view models or we actually had my, my coffees,
um, if you remember here, we had our coffee service remove coffee.
So what we're able to do now that we've registered this, uh, specific
coffee service, um, we can come up here and I can say I coffee
service, I'll say coffee service.
Just like that.
And in my constructor, I'm going to say a coffee service equals all right.
Now, what I'm going to do is say dependency service, just like
we saw before, but I'm going to say, get, and I'm going to ask
to get back in I coffee service.
Now I want you to look here that there is specifically a, um,
Parameter that you can pass in, which is the dependency fetch target.
And that fetch target is either a global instance or a new instance here.
So if you want to get a new instance of this coffee service, every single
time, you can do that for this.
The default is the global instance, because it will be the same exact
database every single time, which is what we want to use in this case here.
So we want to share.
Services between different view models.
That's how you're going to do it.
So now all we got to do is come down here.
Simply say, remove right there and we'll say a weight coffee, service, remove
coffee, and here await coffee service.
So it's no longer a static.
And pretty much there it is.
And I think at this point, yeah, there's another one.
So here is a good example is we have another page that adds a
coffee to the database, so we can do the same exact thing.
Take that by coffee service over here, take this code that
got gets the global dependency.
There we go.
And then what we can do is just drop that down.
So it's no longer static and there we have it.
Now, let me go ahead and compile this up just to make sure we
got all the references there.
Um, it looks like we have one more, which is this coffee service down over here?
Oh, the details page.
Perfect.
So again, we're going to do the same thing here.
I coffee service, put this here.
When I create this page, we're going to get an, a reference to it.
And then.
We'll go over into this page added here and again, drop
down to not use this Singleton.
Now at this point, we're ready to go because we have our entire
coffee service it's been created.
It is.
Injected and sort of the injection part of it is we're taking that
class and injecting it into the dependency services, which can then
go and get it later back for us.
And we're using the same instance of it.
So once it's been created, it'll only create one and it'll keep it in memory.
And if for some reason the garbage collector comes by and sweeps it away.
Well, don't worry because next time you get it back, it will go
ahead and create a new one for you.
So now we're going to go ahead and compile this up and then
deploy it to our Android device.
Let's give it a second here.
All right. Perfect.
So we have our coffees right here.
Let's go ahead and go into my coffee, which is going to be the coffees from
the database, which there are none currently because I just installed
this application fresh, which is good.
Let's go ahead and add this in.
So I'm going to say MOTS, and then I'm going to say new coffee over here.
Hit save, hit refresh here.
And then we should get that coffee back from our database right
there, which is pretty awesome.
I can go.
Of course now go in and let's say I went ahead and remove
this and opened it up again.
So let's go ahead and open up the, my coffee application.
There we go.
And what we should see is if I go into my coffees now, refresh
it up and then we will go ahead and see that there's my coffee.
It's using the same exact dependency, injection service, everything there.
Now I will say this, a lot of people keep asking me like, how come you just don't
refresh the coffees when you hit the web.
And when you come in, I could have done that on this, on appearing.
And I should do that and get the coffees and show them.
But, you know, They're there when I pull the refresh and I'm good to go.
I could tap on one, get some information.
Oh, well, we're good to go.
All right.
So now that we have that in place, let's say we want to, you know,
actually come in and do a little alert whenever I pulled a refresh and put
a little toast message up, right?
Like, oh, coffee's refreshed.
We can do that by coming in and creating another interface here.
I'm going to say new item.
And I'm going to say, uh, let me create a new interface
and I'm going to say I toast.
All right here, we're going to make this a public interface
and we're going to call it the.
Uh, we're going to put in a, uh, I guess a void of make toast string message.
All right.
So that's going to be our one method that we have is we're going to implement the
summer now built into Android is toast notifications, uh, which is quite nice.
So what I can do is come into my Android, uh, application here.
So I'm going to come into my main activity.
And let's just go ahead and come in and create a new class, public class toaster,
and I'm going to implement I toast.
All right.
We're going to bring in that here.
We're going to bring in and implement the interface.
And now all I need to do is say toast dot and then here make text, and then we'll
say, uh, we'll say, uh, platform dot.
Over here.
So we need to get access to the context using Xamarin, a centrals.app
context, the ID, which would be a string that we want to do, but we can
actually just pass any string over here, which is going to be the message.
And then I'm going to do toast, length that long.show.
All right.
So I actually tapped into some Android specific.
No implementations here.
And just like, you would assume I can come up and say assembly,
I'll say dependency right here.
I'm going to bring in that Xamarin forms.
Namespace.
I'm going to say type of toaster.
All right.
Again, bring in this namespace.
Now, whenever I go ahead and add something in here into the database
or pull the refresh, let's do that.
Pull the refresh.
It'll go ahead and do it.
So it's going into my coffee view model.
Now, in this case, we want to make sure that that toast is that Tozer exists.
I haven't implemented in iOS.
Maybe I never will, but let's say over here when I'm done, I want
to make sure that it's not no.
So what I can do is I can say dependency, service dot get I toaster right toast.
Right.
And then I'm gonna do a question, mark dot.
Over here.
And what this does is it's no coalescing.
So it comes in and it says, you know, if this toast exists, this toaster exists.
Call the method.
Else stop a no do anything, which is really, really nice.
So you're, I'll say refreshed.
Okay.
Look at that.
So very, very simple.
So if this thing over here is not, I'm on, I'm on windows or I'm on iOS,
it's not going to do anything else.
If it exists, it will go ahead and pull it up and do the toast that says refreshed.
And then we're good to go.
So this is a really great way of tapping into that native functionality
in case he knows Amarin essentials.
Doesn't give it to you.
It's also nice because you can then implement a fake, I toast in
your unit tests, for example, and then you don't have to worry about
it running on an actual platform.
You can describe what it does.
Let's go into my coffee on a pool to refresh or everything is working.
Correct.
Pull it over there.
It is refreshed right there.
Let me do it one more time so we can see it.
It's now tap, bring into that native functionality via the dependency service.
And there you have it.
It's really just that easy to start using dependency injection inside
of your iOS, Android windows, Mac application with Xamarin forms.
Now I know there's probably gonna be a lot of questions around
IOC or inversion of control.
This is something that, uh, you pass interfaces into a constructor and
then it creates it automatically I'll link to a blog post in which I outline
sort of the Microsoft extensions way.
Of doing this, which is similar to asp.net core and is, which is
how also done at Maui will work.
So this is one of those things where I don't know if the dependency
service will come along for the ride, but there'll be a new way of doing
and Donna and Maui, which is even smoother, which is really exciting too.
But I do like that the dependency services just right there, there
are a bunch of awesome third party libraries out there that you can use.
I just want to show you what's in the box, no need to install any
other new gets or anything like that.
And it's readily available for you.
Hopefully you found this video.
And of course all my videos super helpful in building your xamarinforms
applications out and to get them ready for Donna and Molly.
If you did like the video, give it a thumbs up that goes into
the Google algorithm of goodness.
Of course it recommends it to other individuals watching stuff on YouTube.
And of course, subscribe and hit that notification bell.
And that helps you stay up to date with videos that I'm
putting out here on my channel.
If you want a little bit more, you can also follow me on Twitter at
James Monson Magno and subscribe to my brand new weekly newsletter.
You can go to newsletter dot Monta, magno.com.
It's in the show notes below, and I'll put a banner right here over my face
that shows it, which is quite cool.
I just started that back up and I love to have you.
You know, part of that journey with me as I do my weekly newsletters talking about
all cool things in the world of tech.
All right, well, that's going to do it for this week's episode.
Hope you enjoyed it.
So until next time I'm Jason wants a Magnum and thanks for watching.