.NET Core Console App with Dependency Injection, Logging, and Settings

Поділитися
Вставка
  • Опубліковано 1 гру 2024

КОМЕНТАРІ • 696

  •  4 роки тому +238

    When I see the "I" in the channel's name, I always think it's an interface.

    • @MarioMaletic
      @MarioMaletic 4 роки тому

      lol

    • @YoloMonstaaa
      @YoloMonstaaa 4 роки тому +1

      Truuue

    • @Ny_babs
      @Ny_babs 4 роки тому

      Lol so true.

    • @ibrahimhussain3248
      @ibrahimhussain3248 4 роки тому +17

      public class Myself: IAmTimCorey
      {
      // Now I can do whatever Tim can do...
      }

    • @ericjalbert9433
      @ericjalbert9433 4 роки тому +1

      @@ibrahimhussain3248 For that you should derive the implementation rather than just implementing the interface... because you could say Throw new UnimplimentedMethodException() for each method.... lol

  • @JonathanPeel
    @JonathanPeel 4 роки тому +5

    I especially enjoyed this video.
    I enjoy most of these videos, but I especially enjoyed this one.
    It is greater to watch this, even if you never intend to write a console app, and explains the DI that gets used when writing an ASP/Web app.
    I really like how you will always say "Don't do this in production" and then go back and fix it.
    It can get a little frustrating when going through tutorials that say things like that, but never show you how to actually do it 'properly'.

    • @IAmTimCorey
      @IAmTimCorey  4 роки тому +1

      Yeah, it is convenient to shortcut things since they aren't the purpose of the video, but I hate that too.

  • @TheJessejunior
    @TheJessejunior 4 роки тому +17

    uowwww!!! great content as always, tim!!
    my skills have grown so much since i´ve started following your videos, I usualy watch them several times and they´re my first consulting material whenever I get doubts during daily job....

    • @IAmTimCorey
      @IAmTimCorey  4 роки тому +3

      I am glad my content has been so helpful.

  • @ibrahimhussain3248
    @ibrahimhussain3248 4 роки тому +49

    Yes. I would very much like to see the winforms and WPF version of this.

    • @IAmTimCorey
      @IAmTimCorey  4 роки тому +12

      I will add it to the list. Thanks for the suggestion.

    • @Kevin-mb4xf
      @Kevin-mb4xf 3 роки тому

      @@IAmTimCorey I would love that too. I started with the TimCo video of appsettings, but since I didn't finish the entire TimCo Video list, I didn't have any of the coding in place that you altered, which made it abracadabra for me. :) This video is awesome, am curious how well this translates to WPF project (from scratch). :D
      Thank you for making the time to making this video!

  • @divanvanzyl7545
    @divanvanzyl7545 4 роки тому +3

    Bro your videos are AMAZING. You are covering the topics that we want to learn about, but other people are not covering!

  • @mohammedal-mudhafar4602
    @mohammedal-mudhafar4602 11 місяців тому

    Your content's trustworthiness has become my go-to, when looking for C#/.Net subjects.

  • @sunilanthony17
    @sunilanthony17 4 роки тому +5

    Tim, this is pure gold:
    var svc = ActivatorUtilities.CreateInstance(host.Services);
    Save my life on a few console application that I'm now refactoring to hookup DI properly or the right way. Thanks a bunch.

    • @IAmTimCorey
      @IAmTimCorey  4 роки тому +1

      You are welcome.

    • @iambhanu7
      @iambhanu7 4 роки тому +1

      Can you please explain :Why cant we we get the instance of ServiceCollection, then a ServiceProvider and use the "GetService" method on it to get the instance of the GreetingService.

    • @chursee
      @chursee 4 роки тому +1

      Yes that should work like this:
      var svc = host.Services.GetService();

  • @goodoleme747
    @goodoleme747 3 роки тому +1

    I’m happy to see this. I’m a developer who primarily works on windows worker services / windows services, and a lot of backend applications where there is no user interaction. A lot of people forget that there are a whole realm of developers who aren’t primarily working on web.

  • @AmitDileepKulkarni
    @AmitDileepKulkarni 8 місяців тому

    Thanks Tim for teaching us dependency injection in a very simple way !

  • @oncalldev
    @oncalldev 4 роки тому +5

    As always a very clear, tight explanation of how things work in the .NET world. Thanks.

  • @josepiratilla
    @josepiratilla 3 роки тому +1

    First of all excellent videos!. I wanted to add that at 38:00 another very good reason to pass parameters separately is to avoid the string manipulation if our log level is higher.

  • @jalvrus
    @jalvrus 4 роки тому +3

    Thanks for the underscore tip; that will save me some time. I recently implemented something like this using AddHostedService to register the operation class (GreeterService in your case), and host.RunAsync to execute it. The trick with this approach is to call IHostApplicationLifetime.StopApplication at the end of the operation to terminate the process.

  • @RobertOspara
    @RobertOspara 3 роки тому +1

    Great tutorial :-) Tim treats wachers as human beings: inteligent and smart, because he is very inteligent and smart and tries to predict eventual question or request and imediatelly answer to it. What a great guy :-) But without self-exaltation.

  • @oscarjr2088
    @oscarjr2088 3 роки тому +3

    Thank you so much for this!! I discovered this video after struggling with migrating some code from the Framework to Core. The video demonstrated the functionality in a way that I could easily internalize and use. Subscribing to the Patreon is the least I can do. Be well!!!

  • @parko1965
    @parko1965 2 роки тому

    Tutorials like these are little gems from this man.

  • @KhachaturStepanyan
    @KhachaturStepanyan 4 роки тому

    So well put, I almost never come across a video where you follow tutorial step by step and it works, usually something is missing, something is forgotten
    thank you!

  • @lockegarmin4615
    @lockegarmin4615 4 роки тому +7

    Good video. Just a couple clean up items that were forgotten:
    1. *host* is an IDisposable, so you should wrap it in a using in your main method or call Dispose() manually. This way it cleans up every dependency that you might have living in your dependency injection.
    2. It's best practice to call Serilog's Log.CloseAndFlush() method at the end of your program since you created the logger outside of the hosting environment. If you configure Serilog in the .UseSerilog() method, you don't have to do this (assuming you are disposing host properly).

    • @IAmTimCorey
      @IAmTimCorey  4 роки тому +4

      You are right. I meant to include the CloseAndFlush at the end and totally forgot to come back to it. Thanks for pointing these out.

  • @BlahzayBeta
    @BlahzayBeta 5 місяців тому

    The copy output directory tip was clutch! Exactly the issue I was having. Great video as always. Thanks

  • @mbrotto1970
    @mbrotto1970 Рік тому

    I love the refactoring option (underscore) update...I have been using that for a while now...just popped back as I had lost it...oh and the content is great too ;o) Thanks for the great content Tim.

  • @TaginusOfAinusgard
    @TaginusOfAinusgard 4 роки тому +1

    I actually figured this out on my own when playing one day. However, there are tons of other things I learned in this video that I wasn't aware of. Subscribed!

  • @jerrydsta1056
    @jerrydsta1056 3 роки тому

    This is a fantastic videos that shows how to do dependency injections, logging etc. Highly recommended to all.

  • @bobcynical2316
    @bobcynical2316 2 роки тому

    INCREDIBLE. AMAZING. LIFE-CHANGING.
    THANK YOU TIM.
    YOU HAVE SAVED MY LIFE.
    🙃

    • @IAmTimCorey
      @IAmTimCorey  2 роки тому

      I'm glad it was helpful.

    • @bobcynical2316
      @bobcynical2316 2 роки тому

      @@IAmTimCorey THE MESSIAH HAS REPLIED. WHAT IS EXISTENCE.

  • @JoshuaKersey
    @JoshuaKersey Рік тому

    This one had a lot of great information in it. Thanks Tim! Keep them coming!

  • @DCombsify
    @DCombsify Рік тому

    Thank you, Tim. This is exactly what i have spent the last day trying to understand. I should have looked at your video hours ago. lol

  • @mohamadkibaly808
    @mohamadkibaly808 Рік тому

    That's a great start for Console applications
    Thanks Tim 👍

  • @krsharodh
    @krsharodh 3 роки тому

    Brilliant! It helped me with a coding assignment for a job.

  • @oriwiesel5363
    @oriwiesel5363 3 роки тому

    I so happy that you and I are living on the same time!
    Thank you!

  • @conaxlearn8566
    @conaxlearn8566 4 роки тому +2

    25:54 I totally agree! It was so pointless to look at Microsoft documentations a few years back. Now they even have little walkthrough tutorials, although for me to read the documentations can sometimes be a bit overwhelming. So tutorial videos like yours are still very precious. 😅

    • @IAmTimCorey
      @IAmTimCorey  4 роки тому +1

      I'm glad I'm able to add to the body of knowledge.

  • @rodrigo6459
    @rodrigo6459 4 роки тому +1

    This was a REALLY cool thing to watch... just like 2 weeks ago i was trying to add Dependency Inyection to my console app but i was looking forward to use native microsoft stuff.. Thanks for this!

  • @scottridings6008
    @scottridings6008 4 роки тому

    Best explainer on the internet!

  • @lambda-snail
    @lambda-snail 3 роки тому

    When you talked about how reading the error message helps, I remembered some really bad moments I have had with a certain C++ compiler xD I think the C# compiler generally does a good job though, as you say, so that's a relief. Thank you for the video, it's great as usual :)

  • @danielweaver6110
    @danielweaver6110 4 роки тому +6

    Great video. I think showing how it is used in a WPF MVVM app would be great as well.

    • @IAmTimCorey
      @IAmTimCorey  4 роки тому +1

      Thanks for your vote.

    • @tinoh.4573
      @tinoh.4573 3 роки тому

      Realy great video! I would like to see a WPF example too. Thank you!

  • @Benexdrake
    @Benexdrake 2 роки тому

    Thank u for this Video, learning EF Core and DI in Blazor, but seeing this in Console is awsome.

  • @pauldechampignon2287
    @pauldechampignon2287 3 роки тому

    Cheers Tim. That is what I was looking for! Great film.

  • @MichaelMoore-zi2yf
    @MichaelMoore-zi2yf 3 роки тому

    You have a great and simple way of explaining things. Very clear.

  • @sathyajithkalyadan2971
    @sathyajithkalyadan2971 3 роки тому

    Thanks Tim, you are a great teacher. The way you explain things makes it much much easier to understand and adapt.

  • @garimasingh6341
    @garimasingh6341 2 роки тому

    You are brilliant , you have explained and cleared my doubts in such a beautiful manner

  • @pietsmitsa
    @pietsmitsa 2 роки тому

    Hi Tim, this was awesome as always. Thank you!

  • @88spaces
    @88spaces 2 роки тому

    Thanks, Tim. This video helped me a lot. I liked the underscore tip. I've been wanting to figure that out for a while. And using Serilog looks very promising.

  • @jexter7200
    @jexter7200 3 роки тому

    Great video, thank you for taking the time to explain a few of the 'simple' things. If you don't know a few of them good enough, they are not simple

  • @aprivi
    @aprivi 7 місяців тому

    As always, very good content!!!

  • @shuaibahamed8692
    @shuaibahamed8692 3 роки тому

    Dude I have learned so much from this channel

  • @panagiotisveranoudis3025
    @panagiotisveranoudis3025 3 роки тому +2

    Great stuff, appreciate the time and effort you put into this. Really high quality material.

  • @serjnell4089
    @serjnell4089 3 роки тому

    Best explanations on subject as always!

  • @TheHosuwisp
    @TheHosuwisp 4 роки тому

    This video is just the epic way to understand complicated things. Well done.

  • @ssushovan
    @ssushovan Рік тому

    This is an excellent tutorial. Thanks, Tim!😊

  • @Tolg
    @Tolg 3 роки тому +4

    It would be awesome if you could do a video on how we would best create Unit Tests for such a project and test the services that are expecting the ILogger and IConfiguration to be dependency injectected.

    • @tomthelestaff-iamtimcorey7597
      @tomthelestaff-iamtimcorey7597 3 роки тому

      Tim has done multiple videos on Testing, but I will add the suggestion to his list. Explore these to see if they address what you need - ua-cam.com/users/IAmTimCoreysearch?query=test

  • @kopilkaiser8991
    @kopilkaiser8991 Рік тому

    I was looking for a video like this. Thanks to you. I was able to understand and achieve this.

  • @sarracenogamer7375
    @sarracenogamer7375 2 роки тому

    I love your tutorials step by step, thank you for share your knowlage :)

  • @migueljara8692
    @migueljara8692 Рік тому

    Thanks for sharing this, Tim., very well explained!

  • @maheshshinde4168
    @maheshshinde4168 3 роки тому

    Thank you Tim! It is helping me understand this concept in detail.

  • @hamidrezaashkiyan
    @hamidrezaashkiyan 4 роки тому +1

    It's funny, I just needed this and you posted a video about it. AMAZING!

    • @IAmTimCorey
      @IAmTimCorey  4 роки тому

      Hope you enjoyed it!

    • @fernandopelacini5662
      @fernandopelacini5662 4 роки тому

      @@IAmTimCorey Same but for a Windows application so doing some changes after watching video

  • @heradsinn
    @heradsinn 3 роки тому

    As always, extremely useful! I recommend this channel whenever I can to my colleagues and friends!

  • @Azcane
    @Azcane 4 роки тому +6

    Great video, as always. Just a small nitpick.
    I wouldn't recommend choosing "Copy always" as a copy option for a file. This forces the project to rebuild every time you build or start the application. This is especially annoying in libraries as they and their dependencies will always be rebuild instead of only when the content of any file changes. "Copy if newer" will almost always suffice except in special cases with dynamically generated files.

  • @Die_MF_Die
    @Die_MF_Die 2 роки тому

    Awesome lesson, Tim! its very useful for me. Thanks!

  • @wobblyrampack9655
    @wobblyrampack9655 4 роки тому

    Wonderful! Thanks so much Tim. Trying to get up to speed quickly with C# and I learnt so much from this video.

  • @arthinkers
    @arthinkers 2 роки тому

    Very well laid out Tim. Thank you so much and you are right, Serilog is a good tool and with your code right here, anyone can be up and running in a few minutes.

  • @georgesaeid7231
    @georgesaeid7231 3 роки тому

    This was so wonderful, thank you Tim.

  • @medusaskull9625
    @medusaskull9625 2 роки тому

    Excellent explanation as always

  • @MrKaviraj75
    @MrKaviraj75 4 роки тому +1

    Hi Tim
    I really appreciate you doing ML.NET in C#. There are very few tutorials out there, and they are not explaining things well as you. Hope you do ML.NET series :)

    • @IAmTimCorey
      @IAmTimCorey  4 роки тому +1

      I will add it to the list. Thanks for the suggestion.

  • @RalfsBalodis
    @RalfsBalodis 3 роки тому

    This.will.be.hard.to.chew.
    Thanks for the explanations!

  • @marcouitendaal985
    @marcouitendaal985 2 місяці тому

    spent most of yesterday figuring out how to use configuration in a console app, including the build option of the appsettings file to 'copy if newer'
    then i was wondering, how could I make dependency injection work in a class that's being instantiated through the console.
    I figured that it must be some kind of host that hovers over everything, cuz how could .Net do it otherwise, but how to have it active in a console?
    And this morning this precise video showed up. An hour well spent.
    I've been messing with .Net courses on Udemy, but yours is next on the list!

  • @seijumimurasakibara5516
    @seijumimurasakibara5516 2 роки тому

    thank you for the thorough and well explained video! you just earned yourself a new subscriber :) more power to u sir!

  • @simoncampbell-smith6745
    @simoncampbell-smith6745 3 роки тому +8

    Great Video Tim, One question, when the service creates the instance of GreetingService How does it know what values to set the constructor parameter objects to? Can you specify them?

  • @teijeterbals1203
    @teijeterbals1203 3 роки тому +3

    Wow. That UnderScore tweak from 33:57 is brilliant! Never knew this, and never understood why this isn't the default

  • @chillimanfly2859
    @chillimanfly2859 4 роки тому

    Amazing as always, thanks Tim

  • @rociomejia7356
    @rociomejia7356 9 місяців тому

    Tim I cannot give so many thumbs for all times I see this video. :)

  • @davidos533
    @davidos533 2 роки тому

    Thank you! Very much, very good consideration, finally i understand DI.

  • @bendunaway8296
    @bendunaway8296 4 роки тому

    Dude, what a great video. I'm going to check out your site.

    • @IAmTimCorey
      @IAmTimCorey  4 роки тому

      Please do! IAmTimCorey.com and UA-cam channel ua-cam.com/channels/-ptWR16ITQyYOglXyQmpzw.html Purchases directly fund my ability to provide the free content. Thank you for being a big part of making these free videos available.

  • @juanmanuelgordillogonzalez7186
    @juanmanuelgordillogonzalez7186 4 роки тому

    Cool boiler plate Tim, thank you!

  • @ghostfreak1902
    @ghostfreak1902 2 роки тому

    This was a magnificent video and helped me a lot.
    Thanks for your hard work and your awesome channel. Keep up the good work and thanks a lot :D

  • @devongribbin9620
    @devongribbin9620 4 роки тому

    Really great video Tim. Thank you.

  • @pez5491
    @pez5491 3 роки тому

    Excellent! I wasn't doing anything for such toutorial :D

  • @marceloleoncaceres6826
    @marceloleoncaceres6826 Рік тому

    Another great video, thanks a lot for sharing your knowledge and time,

  • @michaelestrinone2111
    @michaelestrinone2111 4 роки тому +12

    I always wonder - how do you, Mr.Corey, find these extensions out of thousands available? What is the strategy ? Sort by download count?

    • @TheJohndward01
      @TheJohndward01 4 роки тому

      Same here

    • @morphx666
      @morphx666 4 роки тому

      I was asking myself the exact same thing!

    • @IAmTimCorey
      @IAmTimCorey  4 роки тому +18

      I read other peoples' code mainly. I see how other people approach a problem and then I take the best parts of what they do and I mix those with the best parts of other projects I have seen. The more code I read, the more perspective I get on useful libraries. This sounds like a great Dev Questions topic. I'll add it to the list.

  • @michaelday6987
    @michaelday6987 4 роки тому

    Serilog is all we use where I work. I remember when I first started working professionally, I had to learn how to write a "REAL" console app, because the insurance industry is loaded with EOD console apps. All I was used to was beginner tutorials, and they are used much different in the real world.

  • @schh486
    @schh486 4 роки тому +2

    I would love to see a continuation of gRPC that goes more in depth, i cant really seem to find any good advanced guides for c# on gRPC including things like Authentication, Authorization, Security, sending caller information metadata, logging etc etc. That would be great! Thanks for all the great stuff you put out, i was just working in my brand spanking new gRPC console app and thought, hmm how do i get dependecy injection working and i found this :)

    • @IAmTimCorey
      @IAmTimCorey  4 роки тому +1

      I will add it to the list. Thanks for the suggestion.

  • @eleonoravasylenko7094
    @eleonoravasylenko7094 3 роки тому

    Great lesson, good examples, thanks a lot!

  • @dyakobaram
    @dyakobaram 4 роки тому +11

    Recently I found out you are Microsoft MVP can you tell us about that? Like how you became one or what are benefits of being a MVP

    • @IAmTimCorey
      @IAmTimCorey  4 роки тому +2

      I will add it to the list. Thanks for the suggestion.

  • @edelbertoreyes3663
    @edelbertoreyes3663 9 місяців тому

    Thank you for sharing. It is very interesting and useful.

  • @AnasM-vg1uz
    @AnasM-vg1uz 4 місяці тому

    Very helpful !!! Thank you very much. you made my day

  • @otmanm4095
    @otmanm4095 4 роки тому

    Thank you very much, you make very great content!

  • @TonTruong
    @TonTruong 4 роки тому

    wow, this is exactly what i looking for in the morning

  • @tomjones984
    @tomjones984 3 роки тому +7

    I'm liking the videos, very informative! My only gripe is that you elaborate a bit too much on simpler topics when the subject suggests a more advanced user.
    E.g. in this particular video you're looking at more complex things such as DI, but you're also guiding viewers through how to add packages and using statements, and basic Visual Studio usage which I don't think is necessary for more advanced topics and drags out the video length unnecessarily.
    If you haven't done one already, I recommend making a separate video specific to these basic setup/IDE-specific features, which you could then simply reference as and when required.

    • @tomthelestaff-iamtimcorey7597
      @tomthelestaff-iamtimcorey7597 3 роки тому +5

      Thanks for the feedback. Tim believes in giving context for what he is teaching and that takes time. His goal is not entertainment or just to dump knowledge on you but true education. Its a constant balancing act and your feedback helps.

  • @immino
    @immino 4 роки тому

    Wonderful content, thank you Tim.

  • @Strateg2300
    @Strateg2300 2 роки тому +1

    Это великолепно, спасибо большое! => It's great, thank you very much!

  • @flaviodalpino504
    @flaviodalpino504 3 роки тому +7

    Hello Tim ! Thanks for another helpful and great video. At 52:24 you chose CreateInstance but wouldn't it be better to use GetServiceOrCreateInstance that accepts the interface as well ? It makes more sense as the advantage of DI is to predetermine what concrete class to use in the services configuration at line 31 making it easy to choose another concrete class right ?

    • @IAmTimCorey
      @IAmTimCorey  3 роки тому +4

      Yep, that would have been a good choice.

  • @skanyer
    @skanyer 4 роки тому +3

    It looks like the builder object is similar to what CreateDefaultBuilder is doing. You're only using it for Serilog. Couldn't you grab the IConfiguration from the service provider in host and omit the builder object?

    • @IAmTimCorey
      @IAmTimCorey  4 роки тому +2

      Good question and I wasn't as clear here as I should have been. We need to grab the config file before the Host is set up so that we can log any errors that occur when setting up the host. That's why we manually set it up instead of waiting for the host and getting it then.

  • @vnuuk
    @vnuuk 3 роки тому

    This video helped - thank you!

  • @wendyslittleprogram3984
    @wendyslittleprogram3984 4 роки тому +1

    Hey Tim, on an unrelated note, have you considered offering your courses on a subscription model? I think many many people would sign up in a heartbeat. Although your current model may already be working fine!

    • @IAmTimCorey
      @IAmTimCorey  4 роки тому

      I do offer a subscription model. The All Access Pass gives people access to all of the public courses on IAmTimCorey.com for a monthly fee. I open access to sign up every couple of months. Registration will actually be opening soon, so make sure you are on the mailing list so you are alerted when it opens. It only stays open for a few days.

    • @wendyslittleprogram3984
      @wendyslittleprogram3984 4 роки тому

      @@IAmTimCorey my bad, i'll be waiting for that email then!

  • @shashankkhandelwal3514
    @shashankkhandelwal3514 4 роки тому +1

    Hi Tim 🙋‍♂️
    I really love the way you explain.
    I have a request. Can you make a series on different types design patterns. I know we already have one video for singleton design patterns but there are other too.
    Thank you 😊

  • @mrsajjad30
    @mrsajjad30 2 роки тому

    Thank you for a great video. Please make a tutorial on how do we set up these services in a WFP application?

  • @WarnerBrosers
    @WarnerBrosers 4 роки тому +6

    Hello, Tim. You asked about what we want to see on your channel. So what about signalr core. I fight with this library several mounths, but I can't understand how to implement relations between xamarin forms client and signalr core server hub. I can't understand how to implement authentication by jwt token with asp identity and how to process authorized requests to hub methods on server. I need to use web api technology. Thank you for any attention to my comment.

    • @IAmTimCorey
      @IAmTimCorey  4 роки тому +1

      That is high on my list of topics to cover. Thanks for the suggestion.

    • @WarnerBrosers
      @WarnerBrosers 4 роки тому

      @@IAmTimCorey thanks for your answer. But I'm already did it)) and I'm so happy. Now I need help with implementing ssl sertificates for asp core app on external hosting. But I don't thing that it is much harder. Thank you.

  • @ibrahimhussain3248
    @ibrahimhussain3248 4 роки тому +2

    The only thing I'm struggling with nowadays is change tracking. It's really hard for me to do that.
    The context.Save() method in EF is very tempting for just this reason

    • @IAmTimCorey
      @IAmTimCorey  4 роки тому +1

      If you are tracking changes in a model, you should have a set command for each property. Use that to track changes.

  • @СергейБыковский-ъ1ъ

    I think I need to subscribe.
    Thanks for the lesson.

  • @Otonium
    @Otonium 4 роки тому

    So enjoyable and clear.

  • @gaborbellak5189
    @gaborbellak5189 4 роки тому +4

    Really appreciate your videos Tim!
    Just a remark: I followed this tutorial but I got an error related to "UseSerilog()".... "ihostbuilder' does not contain a definition for 'UseSerilog'
    I had to also install Nuget package: Serilog.AspNetCore to make it work.

  • @yourittrainer3196
    @yourittrainer3196 2 роки тому

    Awesome video Time. Thank you so much

  • @optionstrader-r6l
    @optionstrader-r6l 3 роки тому

    Very nice and useful tutorial

  • @sergio.diachenko
    @sergio.diachenko 4 роки тому

    Tim, thank you so much, this is so usefull. Additional thanks for some tips and tricks.