Dependency Injection with .NET MAUI Explained! Full Beginner's Guide

Поделиться
HTML-код
  • Опубликовано: 27 ноя 2024

Комментарии • 124

  • @JamesMontemagno
    @JamesMontemagno  2 года назад +29

    Note: That [ICommand] is now [RelayCommand] from the .NET community toolkit!

  • @MichaelBrownPlus
    @MichaelBrownPlus 4 месяца назад +1

    James I’ve been following you for years since my early Xamarin days. I’ve been an MS architect/dev for 25 years, in mostly Azure cloud architecture these days. But I have quite a few Xamarin apps in stores and now absolutely loving MAUI for new apps. You guys are killing it with Aspire, Hiybrid Blazer/Maui (did an amazing PLAID integration using that tech). Keep up the amazing work incredibly inspiring to me.

  • @TVsBen
    @TVsBen 2 года назад +1

    The real wonder of all this really manifests itself when I want to change an implementation. Create a new class that implements IConnectivity and now you've got to go to every page and change the initialization. But registering the service once lets you change which implementation to use at registration/builder time instead of having to go find every freakin reference. So that's really great.

  • @ap00rva
    @ap00rva 8 месяцев назад +1

    This is very helpful to get DI as I have just started migrating from Xamarin to MAUI and one of the problematic migration was FFImageLoading whereby I was using an AuthHttpClient to be injected in the Android MainActivity, using the Helper to get the IImageService class helped here. Also good example for using DI for Pages and ViewModels instead of "newing" up! Keep up the good work.

  • @ericritter46
    @ericritter46 6 месяцев назад +1

    Love it. Please keep making Maui content. I am just diving in and I am super excited.

  • @terry_hutt
    @terry_hutt 2 года назад +5

    I like the way you explain what you can do and also WHY you should do it. I have a hard time explaining to my team members why I want things done a particular way and this really helps me explain the why to them.

  • @bunnyM992
    @bunnyM992 2 года назад +2

    Thank you for the video AGAIN, James. Helps a lot on my new Maui project.

  • @FrancoisMongeau
    @FrancoisMongeau 2 года назад

    58,000 times is more than 2 years - without sleep. We can do without the internet hyperbole. Seriously: keep up the good work, the best explanation of DI I got so far.

  • @tawcreative
    @tawcreative 2 года назад +1

    I enjoy your videos so much. Thank you for taking the time to do them and break stuff down. Also, I've watched so many of your videos that I've watched you go from short hair to long hair!

  • @kopilkaiser8991
    @kopilkaiser8991 Год назад

    Love you brother.❤ I'm always growing my code skills and knowledge all thanks to you. You really explain in a simple way which is very easy to understand.

  • @ScottGrunwald
    @ScottGrunwald 2 года назад +1

    Great video James! I love DI and it's nicely done in MAUI with these tips.

  • @유재만-o4r
    @유재만-o4r Год назад

    Hi James Montemagno, love your videos! 재미있게 잘 봤어요. 한국에서는 이런 강의를 못보는데 감사합니다.

  • @davidpugh9947
    @davidpugh9947 2 года назад +2

    I didn't know about ObservableProperty/ObservableObject before this video. Thank you SO much, it's going to save me a lot of time!!!

  • @h3ferdinand
    @h3ferdinand 2 года назад +4

    Thanks James! Always a pioneer on MAUI content!

  • @4Asteria
    @4Asteria 2 года назад

    Thank you very much for your efforts.
    I did your workshop recently and absolutely loved it.
    Greetings from Austria

  • @alpealp
    @alpealp Месяц назад

    Great video! Great coverage and clean explanation. Many thanks!

  • @alexpinkerton7459
    @alexpinkerton7459 Год назад

    Thanks again James for the absolutely excellent video!

  • @jeff-uq2sz
    @jeff-uq2sz Год назад +1

    Wow this is amazing. Thank you for getting this out there! And thank you David!

  • @kostyantynherasymenko4
    @kostyantynherasymenko4 2 года назад

    Thank you James! I always look forward to new videos about MAUI from you.

  • @stephenmiller4948
    @stephenmiller4948 2 года назад

    James, you are one busy dude!! Great as always!!

    • @JamesMontemagno
      @JamesMontemagno  2 года назад

      Thank you much! I try! Lots of late nights :)

  • @sruthibandi7751
    @sruthibandi7751 2 года назад +7

    Hey James, Can you make any video on automation testing for .Net MAUI Mobile App? Suggestion for any test framework for Xamarin forms app that which is expected to be migrated to .Net MAUI helps.

    • @Wordsalad69420
      @Wordsalad69420 2 года назад

      I my opinion unit testing the UI is a waste of time. Your presentation layer shouldn't't have a whole lot of logic. All the logic should be in your business logic. That is what you unit test. And for that we already have tons of testing tools.

  • @istuart0
    @istuart0 Год назад

    I wish I'd have seen this when I first started with .Net MAUI back in February. I have a few screens in my app and about a dozen VMs. I'd written my own workaround for trying to handle injecting dependencies but it was a bit messy and I felt there must be a better way. And there is.

  • @d9724
    @d9724 2 года назад

    The explaining of James is increible. Thanks so much for the content! if you make a course I'll take it yes or yes!

  • @mubarekabdi
    @mubarekabdi 2 года назад +1

    You did well James. Well explained!

  • @khaledbudajaja6137
    @khaledbudajaja6137 2 года назад

    Awsome James, the DI idea just knocked in to my head. 😎

  • @davidroqueq.4271
    @davidroqueq.4271 Год назад

    I was doing it without Shell, it didn't occur to me that that's why I didn't get out, thank you

  • @ATNL4
    @ATNL4 2 года назад +1

    hehehe I am still watching the tut 😅, but I would like to make my comment is first comment :)) , and I would like to say Thanks James 👍

  • @stephenhauck
    @stephenhauck 2 года назад +1

    I find I need an AppShell view model but when I try to register it and use constructor injection it does not work and complains about a parameterless constructor in the MainPage = new AppShell() .. is this because the "goodness" that makes constructor injection work happens after AppShell is created ?
    Any way to get around this or just create it manually as I do now ?

  • @stkuo612
    @stkuo612 Год назад +1

    Hi James, I really enjoy your videos, can you make a video to talk about how to handle the login in .Net MAUI? Thanks

  • @doogiebones
    @doogiebones Год назад +1

    This is so damn good, your content is incredible.

  • @Нагибабар
    @Нагибабар Год назад +1

    Great video! You wonderful programmer 🤘

  • @xcgasparxc
    @xcgasparxc 2 года назад +3

    Hi James Montemagno, love your videos! Could you make a video explaining how to implement the SOLID principle with MAUI? Coming from a desktop development environment, MAUI feels so different 😨

    • @jewersp
      @jewersp 2 года назад +1

      I don't think it is very different, depending on where you come from, of course. The SOL of SOLID is pretty much the same (especially in C#, but also Java and C++ with slight variations depending on the language), while the I+D might differ a little, but also not terribly much. Essentially, you need to define your interfaces and implementations and then you can inject your dependencies either via the constructor, a dedicated setter method or a dependency service (or you can use other DI/IoC frameworks) to register and resolve dependencies, like James showed in this video where both constructor and dependency service are actually combined in a useful way. What's important to understand here in order to get the most out of MAUI and to apply SOLID, TDD and so on, is the MVVM (Model-View-ViewModel) design pattern. Your business logic lives in the ViewModels or the classes referenced by your ViewModels and that's where most of the dependencies will be located that need to be resolved somehow. That's where the dependency injection approach that James showed here comes in.

  • @billymartin6497
    @billymartin6497 2 года назад

    Great video! I've always been a Prism person, but with Maui, I'm hoping I won't need it. Please show all the advanced tricks with shell that I used to rely upon Prism to do!

    • @JamesMontemagno
      @JamesMontemagno  2 года назад

      Yeah Prism and other frameworks are great based on what you are building and what your needs are. For me what is in the box has been really working well for me and these new feaures are super great ;)

    • @munawarkhurshid1201
      @munawarkhurshid1201 2 года назад +1

      I wish MUAI had something similar to regions in Prism, imagine a tab control and being able to dynamically inject views in Tabs.

    • @MorneWolfaardt
      @MorneWolfaardt 6 месяцев назад

      @@munawarkhurshid1201 Did you ever get a solution for this?

  • @knockout4907
    @knockout4907 2 года назад

    My takeaway was this process removes the DI inception that I've experienced before. DI a db connection into my controller then pass it down to my helper class, etc. It was awful and messy. This example looks to eliminate that mess by injecting the root page resolving any DI down the pipelines as well. Hopefully I understood that correctly lol

  • @earthlingthings
    @earthlingthings 4 месяца назад +1

    You are the best of the best❤

  • @zahaietskyi
    @zahaietskyi 2 года назад +1

    thank you very much, you are cool, keep up the good work

  • @jasminsabanovic869
    @jasminsabanovic869 2 года назад +1

    Wait a moment, can't we just register services as we do in the .NET core and higher versions?

  • @cptechno
    @cptechno 2 года назад

    GENERAL QUESTION: I use Dependency Injection on the constructor of MainPage. The DI data is in MainPage and my application boots without errors. I want to get access to this data from the Index Razor page. How can I do that.? I researched and took several video courses, but I still did not find the answer. It's not obvious! I suggest you make a separate video addressing this topic. I'm sure there are several programmers like me asking the same type of questions.

  • @alexdobrynin
    @alexdobrynin 2 года назад +2

    How do you think is it good solution to know about any page inside viewmodel? I say - No. May be Maui team should consider making some page associations and resolve route by key, not by page. Look at Prism's implementation

    • @JamesMontemagno
      @JamesMontemagno  2 года назад +3

      With shell navigation is it by URL. I just happened to use the name of the page, but you could use anything you want.

    • @egvijayanand
      @egvijayanand 2 года назад +1

      It's just a string property of the name Route. Can take any arbitrary value.
      To make things easy, mostly defined with the page name to make use of typeof() and nameof() semantics that makes it nifty to register and navigate.

  • @TheAdamwest29
    @TheAdamwest29 2 года назад

    Thanks James. I took the leap to net maui. Any pointers about managing state? Do I need to cook up a service back by storage?

  • @leosouza1520
    @leosouza1520 Год назад

    Great video! Do you think we still need a third-party dependency package, like DryIoc, in MAUI? We are having this discussion with the team, and your opinion would help.

    • @JamesMontemagno
      @JamesMontemagno  Год назад

      Shouldn’t unless you aren’t using Shell. But if there is a dependency package you love and know you can of course keep using it. Every library has its own benefits and uniqueness

  • @zephaneas
    @zephaneas 2 года назад

    James, thanks for the great vid. One thing you should be aware of... You installed CommunityToolkit.Mvvm 8.0.0-preview3. Preview3 is no longer available. When I installed 8.0.0 the ICommand interface is no longer there. You may want to upgrade this project.

    • @JamesMontemagno
      @JamesMontemagno  2 года назад +1

      Updated the source code and also left a note in the show notes! Thanks Kevin!

  • @IvarDaigon
    @IvarDaigon 2 года назад +1

    This is a good explanation but having been a developer for 25 years and having used Dependency Injection in several web service projects,
    I still remain thoroughly unconvinced as to why its such a brilliant idea to use everywhere as claimed by many of it's advocates.
    For example: what is the point of registering and then passing the a static IConnectivity object to each view model when you could simply just access it directly in code via Connectivity.Current inside the constructor because it is already static?
    And if you want more control over the Connectivity property then why not just add a static App.Connectivity property to your App Class?
    Also.. if the use of static properties is such a huge "No No" then why does Microsoft use it everywhere in their own frameworks? App.Current, System.Threading.Thread.Current etc
    To me, all dependency injection does is add extra bloat to your compiled code with the bonus of making it harder to debug and step through while also adding to the nightmare that is nuget hell.
    I am all for making code simpler to read and write but not at the expensive of making it harder to support and maintain.

    • @MrLazyleader
      @MrLazyleader Месяц назад

      Yes, most of the modern practices are just adding unintuitive bload to your code for zero benefit. Yet actually important basic functionalities are not fully supported by Maui.

  • @hamedhajiloo1235
    @hamedhajiloo1235 2 года назад

    Hi. Please record a video about Intent-filter in Blazor MAUI

  • @zephaneas
    @zephaneas 2 года назад

    James, one other thing I'm having trouble with... I have plugged in both an Android table & and Android phone. Both have Dev Mode and USB Debugging turned on, but they don't show up under Android Devices. Am I missing something else?

  • @mkgungor
    @mkgungor Год назад

    Hi
    Could you make a video about how to make the .Net MAUI app auto start at boot… Thank you!

  • @NotTheStinkyCheese
    @NotTheStinkyCheese Год назад

    so constructor injection is 'new' for dotnet Maui ?
    I did like how you explained the concept from scratch as DI can be a bit magic if you don't understand what is happening.
    btw I saw 'scoped' too, but that's just a transient with more staying power as it were which can be useful if you don't want something to be a singleton

  • @leonedev
    @leonedev 11 месяцев назад

    Does this mechanism works also for views or just for pages? Because as of now, it does not works when I inject dependency in a view, it will ALWAYS call the default constructor (i.e. parameterless one).
    Please I'm hardstuck on this

  • @moayadmyro2091
    @moayadmyro2091 8 месяцев назад

    I have app very small but when i build releases apk with respect to aot and shrink the apk very big i check apk i find alot of dependences in lib and assist folder which i do not use do you have solution to reduce the size if i delete all targets and i only have one android

  • @priyavenkat1936
    @priyavenkat1936 Год назад

    Hi James, Can you please give some advantage and disadvantage of using dependency injection in viewmodel

    • @JamesMontemagno
      @JamesMontemagno  Год назад

      Well mostly it is just an ease of use thing and makes test ability better

  • @SathishKumar-yn7fq
    @SathishKumar-yn7fq 2 года назад

    Hi James, Can you suggest me any Bluetooth LE framework to communicate with hardware in .NET MAUI. Like read and write characteristics with examples. Need to support both iOS and Android.

  • @ksyha8376
    @ksyha8376 2 года назад

    This video is missing recommendation for scoped vs transient vs singleton for pages and viewmodels

  • @DeakonJim
    @DeakonJim Год назад

    Might not get any reply but might as well try it, is it a must to register the pages as well along with the view models?

    • @JamesMontemagno
      @JamesMontemagno  Год назад +1

      You want to register the pages because you want to inject in the view models directly into them when you navigate.

    • @DeakonJim
      @DeakonJim Год назад

      @@JamesMontemagno thanks a lot.

  • @fernandogoncalves1891
    @fernandogoncalves1891 Год назад

    Addtransient is not working. When I return to that page it doesn't create a new one

  • @orangecake4427
    @orangecake4427 2 года назад

    Thanks man! Why is this not part of the microsoft docs? 😅 awesome!

  • @dino633
    @dino633 2 года назад

    Hi James, great work, thank you a lot! I have a question. In this example of DI, the constructors of the classes being injected are properly called, to prove that one can set a breakpoint. But not the destructors! I create a destructor in a vm, set a breakpoint, and see that it is never called. I know, this is not a bug but a feature. But I don't understand why DI is implemented this way. Could you comment on this a little bit more, why the dtors are not called?

    • @istuart0
      @istuart0 Год назад

      This may be a facile comment, but if you're registering your VMs as Singletons, no destructors / Finalizers will be called.

  • @Gilgameshx
    @Gilgameshx 2 года назад

    Nice video, do you have any course in Udemy? or plannig to create one of MAUI using full blazor?

  • @greghayden2117
    @greghayden2117 2 года назад

    Just like your previous video on DI this one is full of great information. That said, being new to both Maui and XAML, could you clarify something and/or point me to where the following can be explained. At 5:41, we can see the label text is bound to "Count" in the MainPage.xaml and at 6:01, in the MainViewModel.cs, you can clearly see the line with the [ObervableProperty] "int count;" and then in the method we have "Count += 10;". When you debug, everything is equal, so how is it that "count" is equal to "Count". It clearly works, so is this something in XAML, C#, ,Net or Maui?

    • @IvarDaigon
      @IvarDaigon 2 года назад

      neither.. its in the Community Toolkit nuget package.. what it does is create a public property called "Count" that stores the value in a private variable called "count" but when you increment it you should use "Count" because that also fires an INotifyPropertyChanged event to let the XAML interpreter know to update the value on screen automatically. It is basically the Databinding part of MVVM being taken care of by a nuget package that generates code in the background so you don't have to write it yourself.

    • @jshanker2005
      @jshanker2005 Год назад

      Same here. The lower-case 'count' and uppercase 'Count' dichotomy has me confused. I don't see the wiring between 'count' and 'Count 'anywhere and that bewilders me.

  • @davidjackson148
    @davidjackson148 2 года назад

    Hi James. great videos. I'm trying DI and I get this error "No parameterless constructor defined for type 'zzz.zzz.MainPage'." Some googling suggests its not supported yet. What am I missing?

    • @JamesMontemagno
      @JamesMontemagno  2 года назад

      Would need to see a sample. Grab my source code and look

    • @davidjackson148
      @davidjackson148 2 года назад

      @@JamesMontemagno SOLVED I missed this "builder.Services.AddSingleton();" I'm converting a Xamarin App to Maui :)

  • @SankaraKadiveti
    @SankaraKadiveti 11 месяцев назад

    Hello James .. I have a 2D barcode scanning application written in xamarin forms. Now i am trying to convert into MAUI. I am getting lots of issues in it. In Xamarin forms i used Prism controls, ZXing for barcode scanning. Could you please suggest me the best way to do for me

    • @JamesMontemagno
      @JamesMontemagno  11 месяцев назад

      I have a video coming out Friday that will help you out

  • @munawarkhurshid1201
    @munawarkhurshid1201 2 года назад

    Thanks James. Great content. I am having a hard time with commanding in AppShell view model , I am trying to trigger a command from a menu bar that is setup in the APPShell XAML, and it does not work. This behavior is true only for the APP Shell, seems to be working fine for Pages. Thoughts...

    • @JamesMontemagno
      @JamesMontemagno  2 года назад +1

      Hmmm I haven't tried something like that, i wouldn't do bindings directly in the AppShell. You would need to set the binding context correct, but if you have a sample on github send it over to me

  • @enricoroselino7557
    @enricoroselino7557 Год назад

    yes but now my binding context = viewmodel need the IConnectivity because of viewmodel(IConnectivity connectivity)

  • @davidjackson148
    @davidjackson148 2 года назад

    I notice in Xamarin you can uses plain old CSS files (which I like the idea of). Can you do the same with MAUI and if so can you do a video (I couldn't find one). Awesome stuff keep it coming

  • @wolframliermann2883
    @wolframliermann2883 2 года назад

    Absolutely great video.😍 One question. Can you make a video showing us how to switch from classic pages to shell?

    • @JamesMontemagno
      @JamesMontemagno  2 года назад +1

      Well, it would start by just adding shell into your app and then moving over the navigation to the new system. I woudl look through the docs first and get the base setup.

    • @wolframliermann2883
      @wolframliermann2883 2 года назад

      @@JamesMontemagno Thank you so much. I would try it out and I'm really looking forward to your next videos.

  • @alessandrocaliaro3418
    @alessandrocaliaro3418 2 года назад

    Hi James. How can you pass data between pages? Without dependency I pass data in the ViewModel constructor... with dependency??? Thanks

    • @JamesMontemagno
      @JamesMontemagno  2 года назад

      When you navigate with shell you can pass parameters and data easily. Either strings in the uril OR now full objects: see: github.com/dotnet-presentations/dotnet-maui-workshop/tree/main/Part%203%20-%20Navigation

  • @UzairAli001
    @UzairAli001 2 года назад

    What if I want to pass some parameters along with dependencies in vm

    • @JamesMontemagno
      @JamesMontemagno  2 года назад

      Checkout ruclips.net/video/8z8qz-PePlc/видео.html when navigating :) all built in!

  • @kellelein
    @kellelein 2 года назад

    In the MainPage codebehind, why is
    public MainView(MainViewModel mainViewModel)
    {
    InitializeComponent();
    BindingContext = mainViewModel;
    }
    better than
    public MainView()
    {
    InitializeComponent();
    BindingContext = ServiceHelper.GetService();

    }
    Here you use the IoC container..
    In the first example you use constructor injection, but you still have a hard dependecy to MainViewModel... To use it correct, should you not inject a IMainViewModel instead, and let your IoC bind your interface to your implementation... But I find it hard to understand, how to do it correct, because some clases don't nessary have a interface.. like MainPage typical don't

    • @JamesMontemagno
      @JamesMontemagno  2 года назад +1

      Interfaces shouldn’t be required for a viewmodel as I have never seen that. You totally could if you wanted to though and it would figure it out. Both of them would work.

    • @kellelein
      @kellelein 2 года назад

      ​@@JamesMontemagno Ok... Thank you 🙂

  • @dmedo
    @dmedo 2 года назад

    Why can't you DI AppShell at 16:00 ?

    • @JamesMontemagno
      @JamesMontemagno  2 года назад

      I mean you probably could by registering it with the ServiceProvider... i just didn't try lol

    • @munawarkhurshid1201
      @munawarkhurshid1201 2 года назад

      @@JamesMontemagno Commanding does not work in the VM for an AppShell. Weird perhaps I am missing something.

  • @michaelday6987
    @michaelday6987 Год назад +1

    This is a strange order for your playlist.

  • @walidaywel4081
    @walidaywel4081 Месяц назад

    so i think its time to ditch the xamarin forms

  • @cipriancapus8979
    @cipriancapus8979 2 года назад +1

    9:43 That is one ugly piece of code to access the ServiceProvider

    • @JamesMontemagno
      @JamesMontemagno  2 года назад +1

      Yeah... there are some easier ways to access it. Like every control has access to one, but from my knowledge it isn't exposed at a high level as every window could have a different one... maybe they will clean that up too

  • @harag9
    @harag9 2 года назад +1

    Just trying to pick up MAUI and .NET (Come from a .net framework background. never touched .net until now) -- I'm following along on here and added the community toolkit mvvm package, and ICommand (@6:09) does not exist as they have now renamed it to RelayCommand.
    Thanks for the videos James, fairly new sub here, looks like you have a lot of info.

    • @JamesMontemagno
      @JamesMontemagno  2 года назад +1

      I’ll make sure to make a note as I have in other videos

  • @john-blair
    @john-blair 2 года назад

    Xamarin is meant to be platform independent so it is disappointing to see conditional compilation in the ServiceHelper to get the injection service for the different platforms. The nuget package Microsoft.Extensions.DependencyInjection handles constructor injection with no conditional compilation required for ios and android platforms. Thanks.

    • @JamesMontemagno
      @JamesMontemagno  2 года назад

      Yeah, you could totally do it without any constructor injection at all. All you would need to do is call the class the same name and the namespace be the same and then it would work just fine. Maybe i'll do a video on this.

  • @mieszko5260
    @mieszko5260 2 года назад

    Hey James, thank you for the video!.
    Just one thing, wouldn't be better to set BindingContext in the XAML, so you can take advantage of intellisense for your binding context in XAML? I mean to declare something boomer called ViewModelLocator in App.xaml where in the class ViewModelLocator you have readonly properties with your ViewModel resolved from the DI container (public MyViewModel MyViewModel => ServiceHelper.GetService() ) and use at your page xaml like BindingContext="{Binding MyViewModel, Source={StaticResource Locator}}"?

    • @JamesMontemagno
      @JamesMontemagno  2 года назад +1

      It is better to set the compiled bindings setting x:DataType. You get all the same intellisense and then will get all of the dependency injection for free without a locator or anything. Choose whatever works for you.

  • @sundinmikael
    @sundinmikael 2 года назад

    Is this better to have a static global method compared to use dependency injection and use IServiceProvider to get the service?
    I added a example to easier understand.
    class page{
    public page(IServiceProvider serviceProvider){
    var myService = serviceProvider.GetService();
    }
    }

    • @JamesMontemagno
      @JamesMontemagno  2 года назад +2

      I don't think that adds any extra value at all and really you should just pass MyService in.

  • @cdrbvgewvplxsghjuytunurqwfgxvc
    @cdrbvgewvplxsghjuytunurqwfgxvc 2 года назад

    [ICommand] -> [RelayCommand] hope it saves someone a little time