Building Your First Clean Architecture Use Case (Vertical Slices, Unit Testing With AI)

แชร์
ฝัง
  • เผยแพร่เมื่อ 27 ม.ค. 2025

ความคิดเห็น • 92

  • @MilanJovanovicTech
    @MilanJovanovicTech  5 หลายเดือนก่อน +7

    Simplify your development process - download my free Clean Architecture template: bit.ly/3Andaly

    • @stasasekulic6917
      @stasasekulic6917 5 หลายเดือนก่อน

      Do you use Vertical Slice Arch in course?

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน +1

      @@stasasekulic6917 Not explicitly. But everything is organized around slices. There's a respective slice in each layer.

  • @gigantedocil
    @gigantedocil 5 หลายเดือนก่อน

    Really great! I know that in .NET you usually have a separate project for the tests but I like to put them next to the use case on the vertical slice folder. I think that works really well.

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน

      So your "use case" project is also a test project? 🤔

    • @gigantedocil
      @gigantedocil 5 หลายเดือนก่อน

      @@MilanJovanovicTech Yes. You can exclude the dlls and the files for the release build if you are worried of having them there.

  • @LongNguyen-d2g
    @LongNguyen-d2g 5 หลายเดือนก่อน +1

    Great video.Thank you for your work!

  • @battomisaadi9251
    @battomisaadi9251 5 หลายเดือนก่อน +2

    love your content! Could you make a tutorial on generating presigned URLs and uploading files to an S3 bucket. Thanks for all your great work!"

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน +1

      Can do, that's a great topic!

    • @battomisaadi9251
      @battomisaadi9251 5 หลายเดือนก่อน +1

      ​@@MilanJovanovicTech
      Thank you so much it's been a 3 days stuck on it i get the url but when i try upload to s3 always fail😢😢😢

  • @KristianS93
    @KristianS93 5 หลายเดือนก่อน +1

    Would you generally recommend to create your own JWT implementation rather than using the bearertoken services from identity ?

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน +2

      No, I recommend using an Identity Provider. But it doesn't hurt to know how things work under the hood. :)

  • @ordinaryBrownDad
    @ordinaryBrownDad 5 หลายเดือนก่อน +2

    @MilanJovanovicTech Great demo thanks, can you please explain how Modular Monolith is different from Vertical Slices?
    To me till now both architecture look similar

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน +1

      Modular monolith is essentially vertical slices on a bigger scale.
      The nuances is how we control communication and data isolation between modules.
      I've made a few videos about modular monoliths, you can check them out.

  • @BillionaireDegenApeClub
    @BillionaireDegenApeClub 5 หลายเดือนก่อน +1

    agreed w/ leaving out DDD when desired as its not a requirement of CA/VS

  • @DrGaurangGupta
    @DrGaurangGupta 5 หลายเดือนก่อน +1

    How will we use the use-case (RegisterUser) in the API? Are all the use-cases supposed to be added to DI container?
    Till now, I’ve been more familiar with the service driven architecture where we have a service and every “use-case” is a method. The service is added to DI container. I suppose what you have shown, every use-case as a class, is CQRS. If I’m right, I know the concept but not very familiar with it.

  • @mdsafikulislam9113
    @mdsafikulislam9113 5 หลายเดือนก่อน +1

    Thanks

  • @mhsn27mhsn10
    @mhsn27mhsn10 5 หลายเดือนก่อน +1

    amazing Video

  • @Ahmedhosnybarbary
    @Ahmedhosnybarbary 5 หลายเดือนก่อน

    Great Milan , but I did notice that you igonre the Mediator is this the new way when using the vertical slices? there no need for the more complication

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน

      You can always introduce MediatR, no problem there.

  • @kimandjasoninflorida
    @kimandjasoninflorida 5 หลายเดือนก่อน

    Great video, I'm going to try this on my next small project. Would you place the implementation of IPasswordHasher and IUserRepository in the Users Folder?

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน +1

      Yes, we can create an /Infra folder to hold the implementations? Whatever makes sense.

  • @GaloGalvez-h9c
    @GaloGalvez-h9c 5 หลายเดือนก่อน

    Thanks Milan, (topic apart) Do you recommend GUID on large DB’s?? Any video about that topic??
    I’m really concerned about DB performance in the future, I appreciate your point of view.

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน +1

      Check out this video: th-cam.com/video/-f03gnTreCU/w-d-xo.html

  • @DiegoC-zt7hp
    @DiegoC-zt7hp 3 หลายเดือนก่อน

    Hello Milan, having a quick question..
    What happens if I have a dependency that is shared between multiple slices?
    Lets pretend we have an IEmailSender infrastructure dependency, that needs to be used after creating a user, and after placing an order.
    Where would you place the interface and where would you place the implementation?
    I have learned a ton with your videos, you are an excellent teacher!! Thank you!!! 🙌

    • @MilanJovanovicTech
      @MilanJovanovicTech  3 หลายเดือนก่อน +1

      Create an Email/ folder and place it inside. What's important is the direction of dependencies. So the implementation can even be in the same folder. I'm actually working on an interesting article to showcase this.

    • @DiegoC-zt7hp
      @DiegoC-zt7hp 3 หลายเดือนก่อน

      @@MilanJovanovicTech Thank you very much! that makes sense :) and I really appreciate your prompt response!!

  • @raycarlbrown-amory3509
    @raycarlbrown-amory3509 5 หลายเดือนก่อน +1

    Fantastic

  • @ArnonDanon
    @ArnonDanon 5 หลายเดือนก่อน

    ​@MilanJovanovicTech returning access token feels to me more like an infrastucture thing for security at the endpoint level than part of the domain itself, I wonder how its feets in the application/domain use case you created here, what abstraction would you pass in to handle it and what would the Handle method return if not a User object?

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน +1

      It's use case as any other. Why wouldn't it be? The handle method can just return a simple string representing the access token.

  • @TahaYasaghi
    @TahaYasaghi 5 หลายเดือนก่อน

    i have a quesction witch is : for what type of project we can/should use Vertical Slice Architecture ? for example for Auth service or some business service it's write to user DDD for Auth service and Vertical Slice for business service ?

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน

      I think it's not the right way to think about it. CA = this type of project or VSA = this type of project. Rather, think about the qualities that you get by following these principles. Then look at your project, and ask yourself if you need these qualities.

  • @gigantedocil
    @gigantedocil 5 หลายเดือนก่อน +2

    Like you mentioned, the userRepository.Exists approach is subject to a race condition. If you went with the database index approach how would you be able to do your second test where you check for a duplicate? It wouldn't be possible, and you would not be able to capture that part of the business logic on the use case. We can already see that there's already a tradeoff between performance and correctness. In order to capture the business logic at the use case level you either have a race condition with the exists approach, or a hit to your concurrency with the lock approach. If you go with the database unique key/index approach you no longer capture that part of the business logic on the use case and can't test. Any suggestions on how to handle this?

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน +1

      @@gigantedocil We dont need to test for a race condition, really. Just the correctness. I have a video on this coming in a few weeks, but TL;DR. Use an index. Catch the DB exception and return something meaningful to the client.

    • @gigantedocil
      @gigantedocil 5 หลายเดือนก่อน +1

      @@MilanJovanovicTech Yes, but what I meant is that you're leaking business rules to outside the domain/use case if you use the index approach. If not having duplicate emails is a business rule then it should be explicit and enforced at the use case level. Now that business rule is being implemented by the database implementation. The domain is not enforcing this rule anywhere and a blind implementation of the repository would not know to add the unique key to the email column. This is a real life scenario that I think shows well some of the shortcomings of doing these type of abstractions and clean code. You could do it at the use case with a lock like you mention, but you would incur a big performance penalty. Anyways, I'll be waiting for your video, interested in what you have to say.

    • @ryan-heath
      @ryan-heath 5 หลายเดือนก่อน

      @@gigantedocil I would say be pragmatic about it.
      The chance this will occur with two people registering at the very same time with the same email address would be very rare if not nonexistent.
      Going the extra mile to have a software lock or other domain logic enforced is not worth the effort.
      Having a db unique index is very cheap compared to anything else.
      And also, an index is somewhat implied by the emailExists method, why not hit two birds with just one (cheap) stone?

    • @gigantedocil
      @gigantedocil 5 หลายเดือนก่อน +1

      @@ryan-heath 100% agree I was just stating that if you go about clean code in a dogmatic way you'll soon find out that you'll run into many issues such as this. The idea that you can abstract all the dependencies away completely ignoring how their implementations work will soon put you in this sort of situation.

  • @rayan_azzam
    @rayan_azzam 5 หลายเดือนก่อน

    Thank you for this valuable video.
    I want to ask is it a good approach to start with CA when we are developing MVP and we want to get to market very soon, or start with other simple approaches?
    Then when we will have time to refactor.

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน

      VSA + some sane abstractions works great. I think with a few more videos in this series it'll start to make sense.

    • @rlarno
      @rlarno 5 หลายเดือนก่อน +1

      My advice: start with the clean architecture + VSA; and make sure the code coverage of the 'Domain' and 'Application' layers is above 70-80%. Given the tutorials and video's here this is not a huge upfront cost, but will allow you to iterate fast AND reliable over the MVP.
      That way you'll be able to grow your MVP into a real production application and not stack up lots of tech debt. Because when the MVP takes off and it is time to grow your market share, you do not want to be in a (bad) place where the only solution is a (huge) refactor (or even rewrite). That will kill your product fast.

  • @ulvidemirsoy2558
    @ulvidemirsoy2558 5 หลายเดือนก่อน

    cool video

  • @BilalKhan-sx9eu
    @BilalKhan-sx9eu 5 หลายเดือนก่อน

    I personally perfer this pattern it is easily understandable.

  • @Testestnoname
    @Testestnoname 5 หลายเดือนก่อน

    Could you share the repo?

    • @eugene5096
      @eugene5096 5 หลายเดือนก่อน

      you need to pay money for this

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน

      Grab the (free) template from the pinned comment

    • @Testestnoname
      @Testestnoname 5 หลายเดือนก่อน

      @@MilanJovanovicTech You are the best!

    • @eugene5096
      @eugene5096 5 หลายเดือนก่อน +1

      @@MilanJovanovicTech thank you dear sir

  • @geraldaburto7712
    @geraldaburto7712 5 หลายเดือนก่อน

    Does this mean that I will have a lot of classes with just a single method in it?

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน +2

      Yes, kinda. That's what a use case is - one piece of functionality.

    • @geraldaburto7712
      @geraldaburto7712 5 หลายเดือนก่อน +1

      @@MilanJovanovicTech is there any other way?
      BTW even though I'm a typescript developer I have found your content very helpful.
      I would really appreciate it if you can do a more complete example, with more than one entity and more use cases, thanks

  • @ryan-heath
    @ryan-heath 5 หลายเดือนก่อน +1

    Homework assignment?!
    I didn’t know I was enrolled into a course … 😅
    Great video!
    Also agreeing with use of primary constructors. Nobody will change the input parameters!

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน +1

      Is that too much to ask for? I can't be doing all the work here 😁

  • @rlarno
    @rlarno 5 หลายเดือนก่อน +1

    Good simple video, simple comment though: You are leaking security info by returning "The email is already in use".
    With a datadump of hacked email/password combos, one could hack into the system.
    I understand this is a simple tutorial video, and you can't capture all the best practices (like doing this TDD style would make it even better)

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน +1

      Even large social media networks return info about something like that. Just tested it with Facebook, for example. We could return something more generic like 'That email address is not available'

    • @rlarno
      @rlarno 5 หลายเดือนก่อน +1

      @@MilanJovanovicTech Big companies will probably have other tech to negate the problem (like rate limiting, and other detection methods) and will not allow to data mine their system.
      We negated this problem by adjusting our flow, as when a user registers we would send an e-mail with a unique link to complete the registration. So 1) the attacker can never know it the email is registered and 2) the user would be made aware his account is potentially exposed. But again, I would not expect you to go all this way or explain it in a nice simple tutorial video.

  • @dangerosa01
    @dangerosa01 5 หลายเดือนก่อน

    We need a special price for Latin America. the price for 1 course is our salary 😂

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน

      There already is, check the course page on my website

  • @frontalachivment3604
    @frontalachivment3604 5 หลายเดือนก่อน +1

    What a shady practice that you highlight incorrect statement under my comment. "wow that’s a bad video with wrong information. " - @ryan-heath you were first with talk is cheap comment and now you doing exactly same. Abstraction brings cost, oop is making gaps in memory allocation which is not cpu friendly. Thats video show exactly that. "Clean code" is at some point a way that it looks like "organized code" but its in cost of perfomance. If you make each request as seperate class, its huge allocation cost in real time systems, in big scale you need to think in different way than just i like this "code visual".

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน

      Would've been best to keep under the original comment 🤷‍♂️

    • @TheRealMrp
      @TheRealMrp 5 หลายเดือนก่อน

      This channel is for serious people where we discuss ideas like adults.

  • @frontalachivment3604
    @frontalachivment3604 5 หลายเดือนก่อน +2

    Clean code, horrible perfomance.

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน +10

      What makes it less performant? What would you change to make it more performant?

    • @ryan-heath
      @ryan-heath 5 หลายเดือนก่อน +3

      @@frontalachivment3604 talk is cheap 🙃

    • @frontalachivment3604
      @frontalachivment3604 5 หลายเดือนก่อน

      @@ryan-heath your comment is cheap and useless. "Clean" Code, Horrible Performance - Molly Rocket type in search bar above, all you need to know is there.

    • @ryan-heath
      @ryan-heath 5 หลายเดือนก่อน +4

      @@frontalachivment3604 wow that’s a bad video with wrong information. The comments are disabled, that’s a telling fact …
      The guy is doing micro measurements and based on those timings he says to never ever use those rules. 🤦‍♂️
      “Clean code” are guide lines as I see it. Use it where it seems fit. Generalizing to never ever use polymorphism becasuse it is “slow” is just laughable.
      99.9% of the code the average Joe is writing doesn’t need to be highly optimized code because the slowness is in the IO not in the CPU.
      From that POV better have maintainable code then super optimized code that only the Einsteins will comprehend and even they are hesitant to modify or extend it …

    • @frontalachivment3604
      @frontalachivment3604 5 หลายเดือนก่อน +1

      @@ryan-heath lol, do you know why games use ecs architecture instead of oop??

  • @dotnetMasterCSharp
    @dotnetMasterCSharp 2 หลายเดือนก่อน

    Awesome and useful content thank you Milan