Vertical Slice Architecture Project Setup From Scratch

Поделиться
HTML-код
  • Опубликовано: 25 июл 2024
  • Get the source code for this video for FREE → the-dotnet-weekly.ck.page/vsa
    ☄️ Master the Modular Monolith Architecture: bit.ly/3SXlzSt
    📌 Accelerate your Clean Architecture skills: bit.ly/3PupkOJ
    🚀 Support me on Patreon to access the source code: / milanjovanovic
    Vertical Slice Architecture is an interesting approach to structure your project. Instead of thinking about layers, you try to group components by features. Vertical Slice Architecture has higher cohesion between components, and finding your way around the project is easy. It's not surprising - everything related to a single feature is in one place. Find out how to implement Vertical Slice Architecture in this video.
    Vertical Slice Architecture
    www.milanjovanovic.tech/blog/...
    Join my weekly .NET newsletter:
    www.milanjovanovic.tech
    Read my Blog here:
    www.milanjovanovic.tech/blog
    Subscribe for more:
    / @milanjovanovictech
    Chapters
    0:00 Clean Architecture vs Vertical Slice Architecture
    2:28 Adding the first Vertical Slice - Create Article
    4:47 Installing MediatR to implement use cases
    7:12 Exposing an endpoint for the Vertical Slice
    9:59 Supporting validation with FluentValidation
    14:10 Creating API contracts and adding Mapster
    16:29 Adding the second Vertical Slice - Get Article
    21:40 Grouping components by feature and cohesion
  • НаукаНаука

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

  • @MilanJovanovicTech
    @MilanJovanovicTech  10 месяцев назад +9

    Get the source code for this video for FREE → the-dotnet-weekly.ck.page/vsa
    Want to master Clean Architecture? Go here: bit.ly/3PupkOJ
    Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt

    • @anandjaisy
      @anandjaisy 24 дня назад

      I have not received the code, with an valid email address.

    • @MilanJovanovicTech
      @MilanJovanovicTech  24 дня назад

      @@anandjaisy Check spam?

  • @dsellers
    @dsellers 10 месяцев назад +22

    Hello Milan, I'd love to see a part 2 that goes beyond the typical VSA post. How does one structure a feature that builds on top of 2-3 other features. If Articles are one feature, the let's assume that Authors is another feature. How do you structure the relationship between Articles and Authors. Have you found any nice patterns for structuring these elements.
    I've seen you suggest putting the domain entities in a separate feature/folder. I think that's another great video that gets into more nuance of this approach.
    TY for sharing.

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад +20

      I'm extending it to a Microservice example next week. And I'll add more features.

  • @rtzzz9772
    @rtzzz9772 7 месяцев назад +4

    Thanks Milan, this is a great example of a sanely organized project that threads a balance between normalization and separation of concerns. Doing by feature seems to be a very good way of allowing both newer programmers to the project to come up to speed quickly and still give more seasoned team members the organization we desire. This example has a lot going for it.

    • @MilanJovanovicTech
      @MilanJovanovicTech  7 месяцев назад

      And the ideas applied here work for any architecture, really

  • @being_aslam_tiger
    @being_aslam_tiger 10 месяцев назад +3

    Huge Thanks for making video on this topic & for a full video from scratch to end. ❤🔥

  • @ThugLifeModafocah
    @ThugLifeModafocah 10 месяцев назад +22

    I loved the VSA, but I implemented last year with separated files. It gets more clean in my opinion.

  • @montanomariano
    @montanomariano 10 месяцев назад +2

    I had the opportunity to work on a project with CQRS and vertical slices last year and enjoyed very much. I didn’t know about it until then, so it took me a little while to get muse around it but once you get it, it’s hard to go back

  • @shadowsir
    @shadowsir 10 месяцев назад +23

    Nice, at my current company we made the decision to try out VSA. We're using MediatR to get all of the cross-cutting concerns out of the way (via pipelines: logging, scoping, tracing, analytics,...). The main differences between our solution and yours are:
    - we map everything manually (because mappers are slow AF in comparison to just manually mapping things).
    - we use a regular API controller per feature in stead of minimal API.
    Conceptually they both achieve the exact same goal :)

    • @volodymyrliashenko1024
      @volodymyrliashenko1024 10 месяцев назад +7

      I still can't understand why everyone tries to use MediatR. Maybe you can bring some light.
      I don't see any problem using services per feature and then you can have decorators to implement logging, validation, etc. Decorators can be dynamically created. I did that to introduce a miniprofiler and at the same time there is no dependency on the miniprofiler pack in the application layer.
      With a service interface per feature you don't need to create files for command and handler, it is more natural flow.
      I would use MediatR for communication between features/components. Like when you create a product you need to send email, so you trigger notification product created and then it will be handled.
      What do you think?

    • @nanvlad
      @nanvlad 10 месяцев назад

      @@volodymyrliashenko1024 totally agree! I believe that MediatR like events should die within a time, because it's just a lazy approach to redirect your request flow. It may be useful in some async scenarios where components lies behind different layers and you need to communicate them directly, but in general it's just useless, especially when you define query/command and corresponding handler in the same file/folder

    • @shadowsir
      @shadowsir 10 месяцев назад

      ​@@volodymyrliashenko1024 that last part is ALSO handled by our MediatR implementation: our "command" (workflow) handlers all output a list of events that can be picked up by a MediatR pipeline to be "notified". This keeps our CommandHandlers pretty much devoid of anything that isn't a business concern (notifying other parts of the code that something happened is NOT a business concern but rather an implementation detail).
      The whole point of having vertical slices is to not have the "clean-architecture style" (large) services that try to do multiple things and leak (often unrelated) code all over the place. Having monolithical services usually causes a change in one feature to potentially leak into other features.
      Sometimes you DO want to share code and in that case, you do want to create a service or even a repository (*shudder*) just for that. It's just not the default way we interpreted "doing" vertical slices.

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад +1

      What does your analytics pipeline do? 🤔

    • @pilotboba
      @pilotboba 10 месяцев назад +3

      Mapster has an option to use code generator, so no reflection, so just as fast as hand coded. Also, you can step into the generated mapping while debugging unlike the black box reflection method.
      That said, hand coding is going to allow to compiler to catch must more error and support refactoring.

  • @nove1398
    @nove1398 10 месяцев назад +3

    Great video, I hope this explains a bit more about VSA. I have so many questions personally floating around, and you touched on many of them in this video. Primarily starting from the foundation so to speak.

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад

      What are some questions you still have after watching?

  • @tanjeerhaque3800
    @tanjeerhaque3800 10 месяцев назад +3

    Great one! Would like to get another video based on VSA best practices, alternative approaches, etc.

  • @pilotboba
    @pilotboba 10 месяцев назад +5

    Having the Feature slice/use case in one file will also help with code reviews and Git diffs... one file to look at only.

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад +1

      That's a big advantage that I didn't remember to mention

  • @samjohnson5203
    @samjohnson5203 5 месяцев назад

    Every approach has strengths and weaknesses. Slices, for me, is a helluva lot easier to conceptualize. Thanks for putting this together in such a clean presentation.

  • @diogosilv4
    @diogosilv4 10 месяцев назад +1

    Hi Milan, what a great demo! Thank you so much!
    I would like to see a new video to continue this implementation, but with different kind of services.
    One good example would be migrating from a clean architecture project to this.
    PS: I loved your pragmatic clean architecure course! Congratulations!

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад +1

      CA to VSA migration could be interesting, yeah.
      I'm glad you got value from the course. 🔥
      Any chance I can bother you to leave a testimonial? 🤞 (if you didn't already)

    • @diogosilv4
      @diogosilv4 10 месяцев назад

      Will do!

  • @omar-fathy01
    @omar-fathy01 7 месяцев назад

    It's very useful and kindly focus in your channel for .Net architecture ❤

  • @TheDrComedy
    @TheDrComedy 10 месяцев назад +2

    At my workplace we use VSA in one of our projects and I think It works great, it is much easier to follow the code logic and make adjustments with everything in a single file.

  • @birukayalew3862
    @birukayalew3862 10 месяцев назад +2

    Thank you Milan. This is very helpful and awesome to adapt the VSA. Please continue more about VSA best practices and other concepts. ❤

  • @kis.stupid
    @kis.stupid 10 месяцев назад +1

    Good stuff! Binge watched!

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

    Definetly gonna give it a go, it makes more sense to me, in a specific project I have, thank you. This was helpful, any advice or tips or topics to understand before go full with Vertical Slices? Thank you!!!

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

      Write some proof of concepts to see how you like VSA

  • @selimyldz3288
    @selimyldz3288 10 месяцев назад +1

    Thanks, great video! Can you cover Unittests and how do we write in this VSA approach as well?

  • @TheBekker_
    @TheBekker_ 10 месяцев назад +2

    Interesting, would have loved some more thoughts on in the end.
    What pros and cons you see.

  • @florimmaxhuni4718
    @florimmaxhuni4718 10 месяцев назад +10

    I think this should be much simple:
    - Why have Mediator when you can have all this into a static function/method (called handler) on the CreateArticle where services are passed from Endpoint.
    - Only think that Mediator bring into the table is when you want to use same handlers from other endpoints/other services and I guess the point is not here because of vertical slices
    -....

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад +1

      Awesome, you can make a video to show us your approach 👌

    • @duznt-xizt
      @duznt-xizt 10 месяцев назад +4

      I also don't really see the point in using Mediatr with VSA. I use FastEndpoints for building endpoints and it has a built in command bus for cross cutting concerns. Mediatr just adds another unnecessary layer of abstraction/indirection IMHO.

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад +3

      @@duznt-xizt FastEndpoints is something I need to look into 👍

    • @florimmaxhuni4718
      @florimmaxhuni4718 10 месяцев назад

      @@MilanJovanovicTech I did it :) ruclips.net/video/fV-tzW4NbI0/видео.html

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад +1

      Huge kudos for actually doing it, and making your own video! I would've left a comment there, but no comments allowed since it's flagged as content for kids.
      Very elegant solution on your end. I think MediatR still wins for the cross-cutting concerns, since it's working with raw requests instead of HttpRequest, so it's simpler in that regard.
      But also take into account that in the videos I have to show simple examples, or people won't be able to follow. And the approach I'm using is more valuable as complexity grows. Not saying it's the only way of doing things, but it's certainly _one of_ the good approaches.

  • @tanglesites
    @tanglesites 3 месяца назад +1

    Great video Milan. However, I think in my opinion, the slice should also contain its own DB Context, domain layer, etc. This way the featrure is more portable. But I like you solution here, this is very elogant and definitely has its own use case. Great job. I know these videos are not easy to make. You are an inpsiration . PS: Sorry for any typos, My nose is about six inches from the monitor, I am between glasses. Lol.

    • @MilanJovanovicTech
      @MilanJovanovicTech  3 месяца назад

      Wouldn't we end up with TOO small slices in that case?

  • @aakashpoojary3968
    @aakashpoojary3968 3 месяца назад +1

    I believe the contracts folder should be under the feature/article folders. My ressoning would be we are grouping classes based on features or use case concerns rather than technical concerns and putting contracts as a single unit would be a bit confusing😂

  • @waliullah7215
    @waliullah7215 10 месяцев назад +1

    I really learned and enriched my knowledge by following your channel. I can't explain how your channel helped my career to the next level. I have one humble request, If you get a chance to make a video about Refresh Token things? some of the best approaches will be really helpful.

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад

      I'll think about it, since i prefer using external identity providers

  • @lettuceturnipthebeets790
    @lettuceturnipthebeets790 10 месяцев назад +6

    Milan, could you explain why contracts are just bunched in a single folder? Wouldn't it be better to put them together with their respective features, so VSA follows the screaming design to the end?

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад +1

      Yes, that also works. I placed them in a separate folder for potential reuse.

  • @nacholupotti3644
    @nacholupotti3644 10 месяцев назад +1

    Wow i thought i would never see a video where you use a library for mapping 😂 becausw you were a big fan of mapping "manually". Thanka for sharing this video, interesting as always!

  • @Tamer_Ali
    @Tamer_Ali 10 месяцев назад +4

    Thanks a lot Milan for that awesome video. keep going 👍
    I hope you create another video about how to organize the folders structure of Domain, Infrastructure, Persistence, Common Exceptions and Extensions in Vertical Slice Architecture

  • @cicpolk
    @cicpolk 10 месяцев назад +3

    Hi Milan. Nice video. Regarding the business logic. Would you have the all the logic inside the handle? How would that work out with aggregate roots? Some BL in handler and some in aggregate roots?

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад +1

      If I'm using rich domain models, then I'd try to place most logic in the domain

  • @ChallusMercer
    @ChallusMercer 10 месяцев назад +2

    Hi Milan, thank you for useful video on this interesting topic. I would like to know what are the best practices for reusing some business logic in VSA approach? I think it is not so obvious because each feature should have possibly loose coupling but reusing business logic introduces some coupling.

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад

      Have an example in mind of what is the thing being reused here? 🤔

    • @ChallusMercer
      @ChallusMercer 10 месяцев назад +3

      @@MilanJovanovicTech for example sending email notifications to users with summary of changed data

  • @joehernandez3231
    @joehernandez3231 7 месяцев назад +1

    I had previously watched this video, but it made much more sense to me after completing your Pragmatic Clean Architecture course.
    One question I do have is on the entities in VSA. I noticed that in this example the Article entity suffers from primitive obsession. Did you set it up that way to keep this example simple, or do you normally go that route when implementing VSA?

    • @MilanJovanovicTech
      @MilanJovanovicTech  7 месяцев назад

      Yes, it was done for simplicity sake. You can still do DDD together with VSA.

  • @th3oth3rjak3_
    @th3oth3rjak3_ 7 месяцев назад

    First off, great video! I did have a question about using the nested classes inside the static class. I can see that it groups all of the features inside of a class with the same name as the file, but other than that, I was struggling to come up with another benefit. What are your thoughts?

  • @abdulelbadwy6203
    @abdulelbadwy6203 2 месяца назад

    Really cool and clear video! But in case i want to use Dapper for the queries and ef core for command? I just put the dapper logic inside the handler method? Really cool btw

  • @blah218
    @blah218 24 дня назад

    I love the VSA. And I prefer to use partial classes for our static FeatureX class whenever the lines of code are too much from the maintenance point of view.

    • @MilanJovanovicTech
      @MilanJovanovicTech  24 дня назад

      I've seen a few ways to approach this:
      - Static class with nested types
      - One file, many (non-nested) type
      - Multiple files, one folder (partial classes fall under this?)

    • @blah218
      @blah218 24 дня назад

      @@MilanJovanovicTech I have to use different file names for the same partial class, like CreateUserCommand, CreateUserCommandHandler, CreateUserExtensions etc, each representing a nested type. It is basically a marriage between first and second approaches you mentioned. The advantage is, I can encapsulate the whole "feature" within the static class and just expose two extensions for IServiceCollection and IEndpointRouteBuilder.

  • @gonzalorf
    @gonzalorf 10 месяцев назад +2

    What about communication between slices? Will you cover that?
    Great video.

  • @Kasiux
    @Kasiux 10 месяцев назад +2

    I once started a project following the vertical slice architecture. But after some time I moved more and more to the Clean Architecture approach :D Don't know why. Now I have in my application layer a folder called Features where all my use cases live grouped by the feature within one file.

  • @mayureshs80
    @mayureshs80 10 месяцев назад +1

    Very informative pattern. What is the dark theme you are using with VS2022?

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад +1

      ReSharper

    • @mayureshs80
      @mayureshs80 10 месяцев назад

      @@MilanJovanovicTech Can you share the link? I am unable to find it on the VS2022 marketplace

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

    amazing

  • @baduy101
    @baduy101 3 месяца назад

    Milan thanks for making this video. Helped me alot whether to use CA or VSA. One question though, so the VSA only use one project and only segragated by folders?

    • @MilanJovanovicTech
      @MilanJovanovicTech  3 месяца назад

      Typically yes. Layering across one layer (project) simplifies things. But you can really do anything

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

    Hi Milan,
    Can we avoid using static class for handlers?
    Won't static classes occupy memory ?

  • @burakkizilkaya5271
    @burakkizilkaya5271 10 месяцев назад +1

    What would you do if you had to develop a CLI in addition to the minimal API? The logic of your handler can also be used for the CLI application. I don't know if VSA concepts can still be applied when multiple applications need to be implemented

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад

      I think it can work. Instead of exposing an endpoint, you would expose a way to call the command from the CLI. Right?

    • @burakkizilkaya5271
      @burakkizilkaya5271 10 месяцев назад

      @@MilanJovanovicTech but what if I want both?

  • @JayJay-nb1sv
    @JayJay-nb1sv 9 месяцев назад +1

    Awesome tutorial but was just wondering why you're using the static keyword for your feature classes?

  • @bogdanborovcanin6581
    @bogdanborovcanin6581 10 месяцев назад +3

    Can you show us implementations of Result, ResultT and Error?

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад +4

      Here you go :)
      gist.github.com/m-jovanovic/aa25b1ae424c985ff8ae696a79b6fe6e

  • @microtech2448
    @microtech2448 10 месяцев назад +3

    So, we would end up going from clean (modules which are separated at their own places nicely) to a mess where everything is being tried to fit in couple of files. I did not like it personally but I appreciate your efforts milan for bringing this out to let us know that how VSA can be implemented in .ner core if needed ever.

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад

      I think you should give a try and see for yourself. This can still be clean. You don't have to put everything in one file. It can be in one folder.

    • @microtech2448
      @microtech2448 10 месяцев назад

      @@MilanJovanovicTech hmm but I am already fascinated by your clean architecture series so I would like to use that bit longer 🙂

    • @awright18
      @awright18 10 месяцев назад

      If you moved the classes out into separate files in a directory named for the use case you'd get the same benefits. I think either approach is valid, the main idea is code that changes for the same reason (use case) is physically close by, as opposed to spread in various directories.

    • @microtech2448
      @microtech2448 10 месяцев назад

      Still not convinced, Then better using 3 layer architecture or use just single project. Why people are investing time learning to go moduler, make it as smaller unit of code as possible, going towards microservices.

    • @DaveRoman-mc4nn
      @DaveRoman-mc4nn 10 месяцев назад +1

      @@microtech2448 Imagine you have 100 controllers, 100 services (use cases) and 150 models (request/response), each representing a technical layer.
      So you have 3 technical layers: controllers, services and models.
      Now if you want to add a feature, you need to jump between the three layers. The same happens if you need to fix a bug, you will need to access three layers to know where the problem happened.
      This is what VSA tries to avoid, not to organize your code by technical layers, but by feature, with VSA you will easily know at a glance what the features of the system are.
      PD: You can also combine VSA with clean architecture.

  • @ramigamal6637
    @ramigamal6637 10 месяцев назад +1

    Hi Milan, thank you for this awesome video but how to communicate between features in the same project

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад

      Why would they need to communicate?

    • @ramigamal6637
      @ramigamal6637 10 месяцев назад

      Ok, in my application I have a 'MdicationsGroup' feature and 'Medication' feature every feature is just a CRUD operations. The Medications feature needs to load MedicationsGropus collection from the MedicationsGroup feature.
      For this I am making the MediatR queries in a shared project.

    • @ramigamal6637
      @ramigamal6637 10 месяцев назад

      It's about data exchange between features

  • @andresvasile2312
    @andresvasile2312 10 месяцев назад +1

    Nice video, I just prefer to keep the Response class in the same file as the Command/Query

  • @mtsmithtube
    @mtsmithtube 10 месяцев назад +1

    What happens when your features share functionality or have a dependency on the same entities? Do you create a Common / Shared feature module?

  • @aj.arunkumar
    @aj.arunkumar Месяц назад

    Hi MIlan... Im a great fan of your videos... i have a question.. do we really need mediatR in this case ? couldnt we instantiate the handler directly in the endpoint because the endpoint does only one thing anyway...

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

      We don't - but it makes things easier when adding cross-cutting concerns. I actually recorded a simplified VSA video, which will release in about a week or two.

  • @umtdr
    @umtdr 10 месяцев назад +3

    Thank you for this masterpiece. Very valuable 20 minutes for my career.
    I think this approach is great for small~ projects. What's your opinion?

    • @taner-saydam
      @taner-saydam 10 месяцев назад +1

      I Agree with you. It's an approach great for small projects and maybe medium projects.

    • @DaveRoman-mc4nn
      @DaveRoman-mc4nn 10 месяцев назад +1

      VSA can be used for any project: small, medium or large.
      The disadvantage of VSA is that you need to have notions of software engineering to implement correctly, otherwise you may end up with chaotic dependencies.

    • @umtdr
      @umtdr 10 месяцев назад +2

      @@DaveRoman-mc4nn Doesn't this apply to any architectural approach already?

    • @DaveRoman-mc4nn
      @DaveRoman-mc4nn 10 месяцев назад

      @@umtdr Yes, but let's say VSA is a special case, you must be very careful that the vertical slices do not depend between different modules, otherwise it will complicate the dependency graph.
      One way to avoid this is to use an intercommunication module or as some call it (shared layer).

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад +1

      This approach works on any project size. Ask Jimmy Bogard, he uses it on very large enterprise projects.

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

    What are the uses of an API contract is it used in a tool for docs? Why is it the exact same as the command but different for query? Are there any use cases to why we have the command/query with their respective API contract request/response?

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

      Being able to separately evolve your command, which is an internal contract...
      From the an API request, which is an external contract

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

    I love it! It's so much easier than grouping by technical layers.
    However, I have some questions/notes.
    1. The contracts are going to be used mostly by external clients, therefore I would see them placed in a separate library/package.
    2. As I understand, the features should stay isolated. But there are cases when a feature might need to call the commands from another feature/s, as separate steps. I know it may seem odd, but is it ok then to violate this principle? I'd assume not, but then how shall we deal with the problem? Duplicating the code/features is clearly not a good option, moving the smaller features in a common folder might work, but isn't odd to have a feature in common when it's only reused once?!
    Personally I'd say it's better to just access directly the smaller features through query/commands. What do you think?
    Thanks and keep up the excelent work!

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

      1. If you're building an API - does that make sense?
      2. Communicate using events, maybe?

    • @joehernandez3231
      @joehernandez3231 7 месяцев назад +3

      @@MilanJovanovicTech on #1, what about building an API for a Blazor front-end?

    • @kell7689
      @kell7689 28 дней назад

      @@joehernandez3231 My question exactly. I think the contracts would need to be in a shared library.

  • @jithin.johnson
    @jithin.johnson 10 месяцев назад +1

    🔥

  • @MiladRashidi-tv6qt
    @MiladRashidi-tv6qt Месяц назад

    Where would you put the EF configuration files for the entities in this architecture?

  • @dio.mercury
    @dio.mercury 8 месяцев назад

    Hi Milan! Thank you for the video, I pretty much like this format.
    Trying to reproduce the sample you've demostrated, I've got two errors related to Tags property (List).
    1. After the /createArticle handling the Tags value should (?) be serialized as a collection, but It goes into database as a JSON representation of the List object itself, not its data - like { "Capacity": 2 }. Actual tags don't reach the table.
    2. /getArticle request failed with an error:
    System.InvalidOperationException: JSON entity or collection can't be projected directly in a tracked query. Either disable tracking by using 'AsNoTracking' method or project the owner entity instead
    , which occurred on the line Tags = article.Tags;
    Would be grateful for any advice.

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

      Seems to be an issue with this feature. I'd configure a conversion and use JsonSerlaizer to handle that property

    • @dio.mercury
      @dio.mercury 8 месяцев назад

      @@MilanJovanovicTech Manual conversion works like a charm, thank you!
      Haven't use EF for a while, and wasn't sure how to properly bake this "owned entity". But seems like it's not necessary, so I'd prefer to get back to Dapper.

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

    What do we do when we have a large database query? Do we use DbContext in the handlers?

    • @MilanJovanovicTech
      @MilanJovanovicTech  4 месяца назад

      What other options would you consider?

    • @patxi4876
      @patxi4876 4 месяца назад

      I think there are two options.
      Injecting dbContext into the handlers. I see it suitable for simple database queries.
      Creating one or more repositories per Feature?? It would have the necessary methods for reads and writes to the database. In this case, I have doubts if the implementation of the repositories should be in a separate folder or assembly, Persistence, or in the same folder as the Feature along with the handler, validator, command, etc.
      Tell me something about where to place repositories in a vertical Slice application with many use cases.
      Thanks!

  • @diamondkingdiamond6289
    @diamondkingdiamond6289 2 месяца назад

    Can you use automapper for this type of architecture?

    • @MilanJovanovicTech
      @MilanJovanovicTech  2 месяца назад

      Sure, but it often doesn't make a lot of sense. There aren't too many mappings.

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

    Would you share the contracts with your UI project? E.G Blazor forms. And then also validation rules?

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

      I never used Blazor in production - so not sure what would be best practice

  • @rkbknowledgeshare5113
    @rkbknowledgeshare5113 18 дней назад

    Hi Milan , I like the VSA but look like implement Unit Test and mock object will little bit hard. Can you create a video implementation Unit test on VSA ?

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

    The Result class dos not have so how are you passing the Guid?

  • @Kingside88
    @Kingside88 10 месяцев назад +2

    I thought you forgot my wish. Thank you Milan

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад

      Sorry it took so long 😅

    • @Kingside88
      @Kingside88 10 месяцев назад

      @@MilanJovanovicTech I have one question: How would you handle for example an Order and OrderItems. Would you create a CreateOrderItems class and call it from CreateOrder?

  • @pawenowak5144
    @pawenowak5144 10 месяцев назад +1

    I'm wondering - is it completely save to use EF Contex if whole feature is in a static class?

    • @pawenowak5144
      @pawenowak5144 10 месяцев назад

      OK, I've just checked with debugger. Thanks, I didn't know that:)

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад

      The class is static, but the handler inside is not

  • @Yooakim
    @Yooakim 5 месяцев назад

    Thank you for makign your videos, really good content. One slight comment on this video, you never dshow the Error.cs class and so it is not obvious what is in that class.
    Great video and subject!

  • @najeraz
    @najeraz 3 месяца назад

    It looks good, but I have been using vertical slices for about 9 years, and the validation is better being out of the handler by calling the validator before the handler using the mediator pipeline.

  • @andreibicu5592
    @andreibicu5592 2 месяца назад

    Hi Milan!
    I'm back with another question.
    I saw another videos of yours regarding this topic. In some of them you created the features in the Application layer, in another ones in the Presentation/Api layer. The latter was proposed in the refactored version. If that's the case, what does it remain in the Application layer ?
    Which approach is better, in the end ?
    What should be kept in each layer ?
    Thank you!

    • @MilanJovanovicTech
      @MilanJovanovicTech  2 месяца назад

      VSA tries to have a pretty flat structure. I'll do some more content around this, as I feel there's not enough information.

  • @alanbreeee
    @alanbreeee 24 дня назад

    Would the tests be in the same file too?

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

    Hi Milan, why do you put the queries outside of the Features/Articles folder, is this a Carter limitation? Doesn't this defeat the purpose of VSA by having related classes within the same feature folder?
    Wouldn't it be better to separate Commands and Queries within the Articles folder?
    Perhaps as follow:
    - Features/Articles/Commands/CreateArticle
    - Features/Articles/Commands/GetArticle
    - Features/Articles/Queries/ArticleResponse
    - Features/Articles/Queries/CreateArticleRequest
    Or perhaps as follow:
    - Features/Articles/CreateArticle/CreateArticleCommand
    - Features/Articles/CreateArticle/CreateArticleRequest
    - Features/Articles/GetArticle/GetArticleQuery
    - Features/Articles/GetArticle/ArticleResponse

  • @_rcs
    @_rcs 4 месяца назад

    Thanks once again. In this video, you're injecting the DbContext directly into the handlers. Is this not tightly coupling the handler to a specific piece of infrastructure? I'm concerned that VSA gives up some of the loose coupling that CA provides.

    • @MilanJovanovicTech
      @MilanJovanovicTech  4 месяца назад

      Yes, this is the case. But does it matter that much?

    • @_rcs
      @_rcs 4 месяца назад

      @@MilanJovanovicTech Perhaps. I thought we should aim for abstracting data mutations behind repositories.

    • @gilvanornelas3163
      @gilvanornelas3163 3 месяца назад

      ​@_rcs we should not aim for it, but understand the trade-offs. Usually, the usual reasons for a repository abstraction are testability via unit test by mocking the repository or mutability by replacing the repository without changing the business. E.g., Change the DB implementation.
      If the test case does not have much logic, it is just reading and returning data, there is no reason for unit tests. You can go directly to integration tests to validate your query and parses.
      About the mutability, how many times have you seen someone actually replacing the DB? I saw it a few times, but usually, it is just overengineering for something that you will not use.
      So, if you have a strong reason for an extra abstraction, go for it!
      This is the beauty of VSA architecture. It is the most straightforward approach until you get a reason to make it more complex.

    • @_rcs
      @_rcs 3 месяца назад +1

      @@gilvanornelas3163Thanks so much, that is really helpful.

  • @aslanamca8225
    @aslanamca8225 10 месяцев назад +1

    Why are you putting the Response classes in separate folder? It makes more sense to me to put them in the same static class with the others. Everything about the operation to be done is in a single class.

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад

      Reusability. Or use the approach you suggested, but live with the duplication.

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

    Hey, i dont have an Error type Result class,what should i do?

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

      Create them? Or use a library that exposes them

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

      @@MilanJovanovicTech which library are you using?

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

      i mean, im making Result class exactly as yours,but i cant understand where to find type "Error"@@MilanJovanovicTech

  • @m5s10
    @m5s10 10 месяцев назад +1

    Let's say you implemented entire set of CRUD operation on articles. How would you handle if you'd get a new requirement that checks permissions. Let's say there's some condition that decides if a current user can interract with the article (any of CRUD operations) based on user, article, time of day, position of the moon, whatnot, but the logic is for example 100 lines of code, so probably something you don't want to copy paste in each handler separately?

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад

      Move that to a service, encpasulating the check. It can live under the Articles feature folder. Or in a separate place.
      Then figure out the simplest place to call it.

    • @m5s10
      @m5s10 10 месяцев назад

      @@MilanJovanovicTech What would be a separate place? In case you really have a cross cutting concern, for example, that for all entities you have a service that checks if that entity can be deleted. It feels like you need a service layer and that kind of defeats the purpose of the architecture?
      I'm not trying to bash or make it look bad, I just don't see a clear way to solve an actual requirement that's more complex than the most basic example. Sure, for POC this is nice, but I've never seen a production code that just reads from the DB and displays it. As you probably know, there are always some checks, calculations, and similar shenanigans :)

    • @DaveRoman-mc4nn
      @DaveRoman-mc4nn 10 месяцев назад

      ​@@m5s10 In your example that logic should not go to any handler (or as some call it, a use case).
      The check should go into a middleware so that it is done before the controller receives the request.
      VSA does not prevent you from being able to share code between vertical slices.
      One of the principles of VSA is that you keep related elements of a feature in one place (high cohesion), however this is not the only principle of VSA.
      Another VSA principle is that its vertical slices should not depend on each other (low coupling). This means that if one vertical slice depends on another, you need to introduce a shared layer that allows communication between the slices.

  • @MiladRashidi-tv6qt
    @MiladRashidi-tv6qt Месяц назад

    Could we use a combination of DDD and this architecture together?

  • @richardaubin1951
    @richardaubin1951 2 месяца назад

    Move the article contracts under Articles folder, as they belong to that feature. Why did you choose to put it in an unrelated folder?

  • @sorathavithey890
    @sorathavithey890 4 месяца назад

    How do separate API for mobile and admin for back office?

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

    Where would you keep your domain related stuff? Aggregates, entities and value objects, domain events.

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

      A Domain folder? Or a Domain project

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

      @@MilanJovanovicTech How would you separate an application into separate projects using vertical slices architecture? Because I wonder if that even makes sense at all if we have tight coupling feature-wise to things like endpoint handlers. The domain layer, okay, it's a standalone thing, but others? I would like to create some app to dive deeper into VSA and I can't figure out a good solution structure. What about App.Core (it would act as presentation + application layer), domain layer, and maybe App.Infrastructure, although I don't know whether it makes sense in vertical slices architecture. What do you think?

  • @hyperpaus
    @hyperpaus 10 месяцев назад +1

    Thanks for the explanation. But...If you push vertical slices this far, what is the point of CQRS? Why not just create an Endpoint per Feature, and implement everything in that one method? Or in a service if you can call it from multiple places? This approach smells a bit like the 'smart UI' anti-pattern. I prefer vertical slices within the application layer of my clean architecture, and using mediator to separate the UI from the application layer.

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад

      CQRS always has a point. It's MediatR you have a problem with. So just don't use it.

  • @user-ow7me1bw5j
    @user-ow7me1bw5j 10 месяцев назад +1

    could you implement odata this project

  • @RicusNortje
    @RicusNortje 10 месяцев назад +2

    Nice video, just a pitty that most of your videos are using CQRS and MediatR, out of the last 3 companies I have worked for none of them use these patterns so alot of what I learn from you I can't directly impliment professionally, only in my personal side projects. Would be nice if you alos used other industry common patterns like the repo pattern etc in some videos.

    • @Rodrick.
      @Rodrick. 10 месяцев назад +3

      Have you found the Repo pattern useful? In all projects I've been in mostly use it, but never , ever did they change from EFCore to Dapper or some change that would make the pattern useful, for me it's been just adding layers on top of layers to the code.

    • @volodymyrliashenko1024
      @volodymyrliashenko1024 10 месяцев назад

      ​@@Rodrick.I found it useful even without changing the database. I like to have all query logic grouped in repository. So it is easy to find and easy to implement. Note: I don't like generic repo, it is useless.
      In scope of VSA, I'm going to try to implement repository per feature. Like data access layer per feature. I think it solves a lot of questions where to add a new query.

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад +1

      Nothing really changes conceptually without MediatR
      Command = Method parameters
      Handler (use case) = Method on a service
      Send(command) = CallService(params)
      Right? 😁

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

    Why are your contracts and entities not in the feature slice?

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

      An entity will be used in more than one feature slice

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

      yeah fair enough, what about response/request though? I saw you put those in contracts folder

  • @haraheiquedossantos4283
    @haraheiquedossantos4283 20 дней назад

    Where would you put your repository abstraction if you must deal with consistency and invariants?
    Inside features folder? Or inside Database folder? 🤔

    • @MilanJovanovicTech
      @MilanJovanovicTech  20 дней назад

      Do we even need a repository here?

    • @haraheiquedossantos4283
      @haraheiquedossantos4283 20 дней назад

      @@MilanJovanovicTech For this sample, we don't. But in a complex project with more sophisticated business we may need repository abstract to deal with consistency on the write side, don't we?
      Hence a repo abstraction could solve this problem. So my question is where would you put it? 😅
      And a repository

  • @dfytq
    @dfytq 10 месяцев назад +1

    What is the difference between clean architecture and onion architecture? I am always getting confused between these two things.

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад

      Same thing, different name. If you search for the implementations of both in .NET, you'll see they are practically identical.

    • @dfytq
      @dfytq 10 месяцев назад

      @@MilanJovanovicTech yes, i have seen it. Do you have clear insights on both of them? If yes, could you please share when and where should we use which one?

  • @Tamer_Ali
    @Tamer_Ali 10 месяцев назад +1

    Is it ok to use Vertical Slice to develop website?

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад

      Yes!

    • @Tamer_Ali
      @Tamer_Ali 10 месяцев назад

      @@MilanJovanovicTech awesome. cannot wait for the next video

  • @16Flavius
    @16Flavius Месяц назад

    Could it still be a Vertical Slice Architecture if you would not add all the code inside 1 class, but have a folder (lets say "Article" as in your example) and in that folder to have the Command, Handler, Controller Api, etc. ? From my point of view, the class can quickly become huge which will make it harder to maintain, read, test, etc.

  • @fieryscorpion
    @fieryscorpion 10 месяцев назад +8

    This is million times better than Clean Architecture. Thanks!

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад +1

      Interesting. Why do you think it's so much better?

    • @aj.arunkumar
      @aj.arunkumar 9 месяцев назад +2

      @@MilanJovanovicTech he probably meant to say "i loved this video better than the clean architecture video".

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

      @@MilanJovanovicTech I think clean architecture is all hype. The real clean architecture is this literally. Clean architecture does not scale well. This does.

    • @matswessling6600
      @matswessling6600 5 месяцев назад +1

      clean architecture is vertical. he is not giving a correct description of clean architecture.

  • @plamentodorov5117
    @plamentodorov5117 3 месяца назад

    For simple cases this "one file architecture" looks good. For real app with services and many use cases(BL) it can become too cluttered. Am I right or I miss something?

  • @mikevaleriano9557
    @mikevaleriano9557 Месяц назад +1

    good content! but when your "get the source code" link is not a github/gitlab repo, but a page asking for your email so the code can be sent... 💀💀💀

  • @arteqppp6223
    @arteqppp6223 10 месяцев назад +1

    I totally do not understand why would I create something like CreateArticleRequest, instead of just using CreateArticleCommand. I dont see any benefit of that, please explain me whats the point of separate "request" class and command. Btw, I was waiting for VSA video from You, I'm so glad You make it!

    • @Isitar09
      @Isitar09 10 месяцев назад +1

      We use commands inside the application context and requests as an api request model
      In the api request model you can add annotations that are relevant for the api (such as query parameter names, FormFile etc.)

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад

      The Command can have additional properties that you fill in internally. If you expose it you are:
      - Leaking internal implementation details
      - Coupling the Command to the API contract

    • @arteqppp6223
      @arteqppp6223 10 месяцев назад +1

      @@MilanJovanovicTech I can think of PUT requests. I need to provide ID in route, as well as whole object in body. Could my "request" class have no ID property, and just then merge ID + request class into command class? Or that case is not common practice?

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад +1

      @@arteqppp6223 That is a common case, yes

  • @crazyfox55
    @crazyfox55 10 месяцев назад +1

    What about non CRUD features?

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад

      What do you think would change significantly?

    • @crazyfox55
      @crazyfox55 10 месяцев назад

      @MilanJovanovicTech I think there would be more duplicate code. Features are usually hierarchical in nature. There are some complex features that depend on another base feature. However, the base would need to be duplicated within each of the complex features.
      There is the concept of push down into the domain model where a feature transitions into part of the domain. What are your thoughts?
      Also, I've seen so many CRUD examples that it's hard to see how this approach applies in more complex scenarios.

    • @DaveRoman-mc4nn
      @DaveRoman-mc4nn 10 месяцев назад +1

      @@crazyfox55 The base feature would not necessarily be duplicated. VSA does not prevent you from reusing modules. You can perfectly well add the base feature in a shared layer and several vertical slices will depend on it.
      However, another detail is to see if it is really a "duplicate code". Several codes can be identical but have different purposes and evolve independently.

    • @crazyfox55
      @crazyfox55 10 месяцев назад

      @DaveRoman-mc4nn Yes, that makes sense.

  • @TellaTrix
    @TellaTrix 7 месяцев назад

    Vertical Slice is way more easy than clean code architecture. I mean practically nobody want to intentionally to make more complicated approach over layer architecture. for simplicity of object separation, indeed it is good pattern.

  • @parthadutta1168
    @parthadutta1168 4 месяца назад

    Dear Milan, thanks for the tutorial. I have been using clean architecture since years now along with the concept of vertical slicing. Per my experience, it's not a good idea to have multiple classes in the same file. Rather we can have subfolder for individual features inside the Features folder and keep the related classes at one place but in different files. In that approach the developers should be disciplined about the naming convention of the files.
    For example CreateArticle feature should have the following files:
    1. CreateArticleCommand.cs
    2. CreateArticleCommandHandher.cs (for FastEndpoints, CrerateArticleCommandEndpoint.cs)
    3. CreateArticleCommandValidator.cs
    4. CreateArticleCommandResponse.cs

    • @MilanJovanovicTech
      @MilanJovanovicTech  4 месяца назад

      That's just a preference. Your suggestion leads to pretty much the same design.

  • @cularu1
    @cularu1 10 месяцев назад +1

    Looks like I've been doing vertical slice architecture without knowing.

  • @md.sayeedrahman2553
    @md.sayeedrahman2553 8 месяцев назад

    I have two questions:
    1. Can vertical slice architecture have separate layer for infrastructure?
    2. Can vertical slice architecture have separate layer for business/service layer?

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

      1. Yes
      2. The slices are the business/service layer

  • @AboutCleanCode
    @AboutCleanCode 10 месяцев назад +1

    I think CA, as described by Uncle Bot, is much closer to VSA as often depicted - ruclips.net/video/7ZXW_oWdTk4/видео.html

  • @maacpiash
    @maacpiash 10 месяцев назад +2

    FIRST!

  • @GaryDelaCruz-Neural
    @GaryDelaCruz-Neural 5 месяцев назад

    I can see how this can get convoluted real quick. Still, I can see why some people would prefer this over clean architecture. Not my cup of tea though.

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 месяцев назад

      Some people will swear by it. It's grown on me, to be honest. But I still prefer CA, too.

  • @fpcastanheira8679
    @fpcastanheira8679 9 месяцев назад +1

    a bit similar to MVC

  • @codingbloke
    @codingbloke 10 месяцев назад +1

    Are those candles real? A naked flame in such close proximity to combustible materials. I found that very distracting and quite worrying, be safe.

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад +1

      Electric🕯, nothing to worry about. But good that they look convincing.

    • @user-xm7sh3vw8o
      @user-xm7sh3vw8o 10 месяцев назад

      🤣🤣🤣🤣

  • @TheEamonKeane
    @TheEamonKeane 2 месяца назад

    Seems way simpler than Clean architecture

    • @MilanJovanovicTech
      @MilanJovanovicTech  2 месяца назад

      Clean Architecture IS simple. The problem is devs who make a mess of it.

  • @caseyspaulding
    @caseyspaulding 9 месяцев назад +1

    Man, you to good at this. Very helpful. You remind me of how much I need to learn.✍ So we dont care about the Single Responsibility stuff because we put everything on one class. Also why did you create the folder Contracts.? Why not put it in the feature folder?

    • @MilanJovanovicTech
      @MilanJovanovicTech  9 месяцев назад +1

      Not that we're not honoring SRP here to some extent. You can consider an entire feature as a single whole that we're modeling.
      Contracts folder for potential reuse.

    • @caseyspaulding
      @caseyspaulding 9 месяцев назад

      @@MilanJovanovicTech thank you

  • @kaizer-777
    @kaizer-777 8 месяцев назад

    This is an interesting approach, but I think you're limiting yourself by placing all of these concerns in a single file. Some larger systems I've worked on shared code across multiple environments, some web-facing, some windows services, console apps, etc. It wouldn't make sense to me to have API routing buried in my classes that I'm using in a console app. There's also something to be said for enforcing decoupling when the implementations are separated via project boundaries.

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

      Obviously I would build that kind of system in a different way. Architecture is context-specific. Right?

    • @kaizer-777
      @kaizer-777 8 месяцев назад

      @@MilanJovanovicTech It is, but planning ahead is also a thing.

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

    Why I never understand your videos ! I think you need to lower it a bit or simple it more !

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

      No idea

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

      Milan answered humble yet. 😂 Congrats dude. Excellent explanation about Vertical Slice Arch.

  • @jasongallavin2917
    @jasongallavin2917 5 месяцев назад

    You are still organizing your project by technologies and not your features. You only implemented the vertical slice in one layer. I expected to see a bit more organization here

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 месяцев назад

      Should I create a DbContext per slice? Not sure what you'd expect. How would you organize this better?

  • @user-xm7sh3vw8o
    @user-xm7sh3vw8o 10 месяцев назад +1

    ValidationBehavior can be used ,,,like
    👍👍👍👍👍👍👍