All right.
You asked for it, you left comments and all of my architecture videos.
So we're gonna talk about architecture yet again.
That's right.
We're talking about MVVMS that's right.
It's my architecture pattern that I've used for the past 15 years,
from my very first job, all the way into the most recent app that
I've deployed into the app store.
I'm gonna break down exactly what MVVMS is and why I think it's so important and
help answer your questions along the way.
So let's get into it.
Hey everyone.
I'm James.
And I'm back with another video this time talking about architecture, because
you had many, many, many questions.
I just put out a video, not too long ago about M VVM model view,
view, model architecture, which is all about architecting code
specifically for doing data binding.
And it works really nice with things like SAML UI.
So if you're doing things with .net Maui or UWP, or w I three or Avalonia or.
UNO or any of these platforms is gonna work super duper great, because it
has two way data binding built in.
We talked a lot about what it looks like to put your code just in the
code behind, and then what it means to put your code in an MVVM architecture
pattern that makes your code testable and makes your code decoupled.
And additionally, it makes it really nice to do that.
Cool data binding back and forth.
Now, many of you had questions though.
Some people.
What about the model?
And then some other people said, what about the view model?
And then other people said, what about the services?
Well, okay.
and a lot of people had questions.
Like how smart should things be?
Should the model be smart?
Should the view model be smart?
Should the services be smart?
Like what should actually happen here?
And it is all good questions, to be honest with you.
And I'm gonna break down.
My specific architecture pattern is that I've used for the last 15 years.
I started my career off working at cannon the camera company, but I
worked on big printers like this one here, uh, and different, uh, flow job
management software, uh, over there.
And everything was interface based.
We had interfaces for everything under the sun, and I thought that was really
great, uh, because it makes things really decoupled and really testable.
While I like interfaces.
I don't like to go interface overload, to be honest with you.
I like just some interfaces when necessary.
Now MVVM S the S standing for services is the most important part of my
architecture pattern that I use.
I didn't create it.
I didn't invent it.
I just added an S to the end of MVVM and that's my services.
So I think the best part of demoing what this means and why I use it personally.
And why I think that you should.
Look at this way of decoupling certain pieces of functionality, uh, away from
other parts of your application, uh, as much, or as little as you need to, um, is
in actually the monkey finder application.
For my.net Maui workshop.
Uh, and this is a app that I've built over the years and
turned into a.net Maui workshop.
And over a hundred thousand people, I've watched my video,
which I put up right over there.
Uh, that's four hours long walking through the application, but this
architecture pattern and MVVM S and using your services, like I said, I didn't
invent it and you can use it in any application type, uh, that you're using.
So if you're doing WPF or things like that, you're good to go.
Let's go ahead and get into it.
All right.
The very first thing we're gonna see is the monkey finder application.
This application's relatively simple.
You say, get monkeys.
It goes off to an internet service provider, does a restful service call
or reads from a file, this monkey data.
And then you can tap on a monkey, it navigates to set monkey, and then you
can also find closest using geolocation.
You can go ahead and open on the map and it opens it.
Now let's head into visual studio 2022.
And take a look.
Now, the first thing that I want to talk about is just thel here.
So again, this is using straight MVM architecture pattern.
We have my data type here, which is giving just some in inte sense to the, um, User
interface and also doing compiled binding.
So if I do a typo or mess something up, it'll let me know.
I have, uh, some standard commands here.
So when I pull the refresh, uh, that's gonna go ahead and
hit the get monkeys command.
There is, is refreshing.
There's a collection view with monkeys as the item source.
And then we simply bind up a whole bunch of different things like tap
gesture, recognizers, uh, image, uh, different labels inside of
here with that monkey information.
So nothing too crazy.
And here we go.
We have buttons.
We have activity indicators straight M VVM.
Now, if we pull out my solution and I zoom in over here, we
can see that I have M V VM.
And services . Okay.
So the services, unfortunately, alphabetically doesn't align with exactly
how I would like it, but I do this here.
Now.
I also do view and sort of views and sort of view models because I actually
like it to say model view, view model.
I'm just, uh, I don't know.
That's just me.
I, I just can't help myself.
Uh, I guess I could do.
Something instead in front of services to make it go to the bottom.
Uh, but you know, even there's other folders in between it now,
the first question many people asked was what about your models?
James?
You forgot about talking about models and MVVM okay.
Well, I kind of did, but models should be very primitive.
In my personal opinion, you can actually look at my monkey class here.
A monkey class doesn't know anything about anything really.
Uh, in general, I think.
These are simple, uh, objects that are just used temporarily to hold data.
They really shouldn't know too much about anything.
Maybe you override, uh, some comparison methods.
You override some two string methods, but an ideal world.
In my personal opinion, they shouldn't do anything.
Uh, one caveat to that, I would say.
If you are doing, um, some certain things, they, they may, for example,
hold some data such as, you know, I want to do a display name or I
want to give you the first letter.
Um, you know, and those might be things that aren't in the database
or they might not be inside of, um, the, um, JSON fee that's coming.
But in general, I think that these should be very, very simple.
And if you look at a lot of my applications that are on my GitHub,
you're gonna see that this is how I structure almost all my
applications and my data objects.
They shouldn't be computing stuff.
They shouldn't be doing very much.
They should just be sitting there, their models.
They're just around, not doing much at all.
Uh, they may, for example, B have a database object type, or you might
decide that that database object type is separate from your model based if, uh,
you're sharing that database model across.
Now, when it comes to view models, those also should be relatively not.
Intelligent.
I think in my personal opinion, I would say that this here is an example
of something that's in the middle of MVMS, uh, in my personal opinion.
Uh, but, uh, when it comes to the view models, I don't really
think they should know too much of where the data is coming from.
They shouldn't be querying a service.
They shouldn't be querying a database.
They really shouldn't be doing much.
So this is my base example here inside of my view model.
And.
What we can see in the constructor is it takes in three different, uh, pieces
of information, a monkey service, eye connectivity, and IGO location.
Now some may argue here that I might have my own connectivity service
and my own geolocation service that take in these interfaces.
But I do think that in general here, uh, this is a pretty decent practice based
on what those interfaces are giving you.
If you do have, uh, and do need to do a lot of computation around
connectivity or geolocation, you might put those in their own separate
class and their own separate service.
So, if we look specifically at the get monkeys command,
this is a great example here.
The first thing I do is I use that interface and I check if there's
connectivity and here I just, you know, check if it's the internet does not equal
internet and pop up a display again, this could be a its own service, right?
It could be, uh, you know, a weight.
Connectivity dot check internet, for example.
And we remove this decoupling of, of checking for connectivity here, because
we might wanna reuse that logic later on depends how advance your app is, but the
most important about the actual services.
And when I look at a service, I think about making a restful service
call, hitting a database, making authentication service, things like that.
We simply say, monkey service, get monkey.
Notice here that the view model is not tapping into a database.
It's not tapping into a restful service call.
It's not tapping into reading information from a file and desal it because we wanna
decouple that completely is to make that component really testable and reusable
across different parts of the application.
The only thing that the view model really cares about is that list of
monkeys that it's going to data bind.
And specifically any properties that it's going to also data bind up to
see if it's refreshing or it is busy and that's kind of it down here.
We can see, this is a good example of maybe this should have been , you
know, a, a service, a geolocation service where we're getting last known
location or getting the location.
Ay.
So those are kind of a mixed bag where like MVMS light in a
way if I was to do it that way.
But if we look at the service.
And introducing this pattern.
There is one service inside of here, which is the monkey service.
Now, what I like about this monkey service is that we're able to put it behind an
interface if we wanted to totally up to you, if you want that to be completely,
completely decoupled, and you want it to be an interface, you can do that.
Like my IGO location, an eye connectivity, that's coming in from.net Maui.
But here, what we're going to note is that the monkey service
itself is gonna be in charge of.
The H C T P client, if this was a database for the monkeys, it would be
in charge of accessing that database.
Uh, this could be the database for the entire app, or maybe just for the monkeys,
it's up to you on that granularity level and that connection that you have.
Here.
This is the code that we do not want into our view models.
I think that view models should be light to medium, so they shouldn't
be making restful service calls.
They shouldn't be handling status codes.
They shouldn't be decentralizing information, whether
it's from the internet.
Or if it's from a JSON file or from a database now what's nice about this,
is that at any point I can come in, I could easily test this application
and this logic, and then my view model over here knows nothing about it.
If I wanna now add another method called get monkey and pass an ID and do other
things like that, it's completely removed completely detached, a hundred percent.
So we look at the model.
Super duper simple.
The lightest of lightest weight really knows nothing about
anything view models here.
Ideally, as we can see coming in from the constructor, which is using the
built in dependency injection, um, this is going to be very, very minimal.
It doesn't know about the connectivity.
It doesn't know about the geolocation.
It doesn't know about the monkey service.
It just knows what it can call on it.
What's being expos.
Then we have the service, the thing that's doing the bulk of the work
that is independent from the user interface and independent from the
state of the user interface completely.
So I think that these are great examples of, like I said, databases, reading
from file making restful service calls, and those can be as granular or.
Non granular as you want inside of your application.
And the thing that I love about this is that it all works very, very nice
with the built in dependency injection service, especially for using, let's
say in .NET Maui, for example, um, you are using, uh, shell, that'll be
injected into the pages, into the view models, into the services across the.
But there we go.
That is my M VVM S architecture pattern.
What do you think?
Do you have more questions that I not answer anything?
Do I need to make another video on architecture?
Let me know.
In the comments below, I do read all of them.
I try to answer as many as I, as many as I can below, uh, down there.
Of course, I really appreciate.
Everyone's been hanging out on the channel, leaving comments, leaving
those likes, and of course, subscribing and tapping that notification bell.
So you get subscribed and you get notifications every single time I
put out a video, you can hit that notification be, and it'll just
come up in your subscriptions feed.
I do that for some channels based on what you want, but I put out videos
almost every single week here on my YouTube and I also live stream.
So those notifications do help there as.
Let me know if you have any more architecture patterns, I will continue
to do MVM videos until the day I die.
I think , uh, because I love it or until something replaces it.
Uh, but for me, I love it.
And I love my architecture pattern.
As I said, I've used it in almost every single application that I've ever built.
You can take a look, especially at my, uh, let's my other applications
on my GitHub, the island tracker.
Application's a great example.
Um, I think also the podcast application.
Also very similar and that one, even architects out, um, more
of those individual services.
Uh, so you can see that there, now this has just been one in my many, many
series of MVM and architecture videos.
I'll put links below to all the other videos.
And of course, to that four hour long video, all about getting started and
building your first applications with.net Maui, hope that you enjoyed this video.
If I did, if you did.
Thumbs up it super helps out, goes into that YouTube algorithm of goodness.
Really appreciate it.
Hope you have the most amazing day in your entire life.
If you have any questions, let me know until next time.
Thanks for watching.