Getting Started With MediatR and Vertical Slices in .NET

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

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

  • @nickchapsas
    @nickchapsas  ปีที่แล้ว +63

    This is the first video in a 3 part (for now) series. The benefit of using MediatR will become way more apparent as we use more of its features in future videos. Subscribe so you don't miss out.

    • @WilGarcia-k9h
      @WilGarcia-k9h ปีที่แล้ว +2

      I was waiting for your take on Vertical Slices. Thanks man!

    • @lukaszluczko
      @lukaszluczko ปีที่แล้ว +1

      Greate video, where can I find Your code?

    • @ritchieedworthy9177
      @ritchieedworthy9177 ปีที่แล้ว

      Great video, are you still playing with the source generated mediator. I like the concept and moved a few projects to it but confess I haven’t actually benched the results to see the improvements (or slow downs)

    • @KosPerera
      @KosPerera ปีที่แล้ว

      Where can I find the demo code?

    • @mohamedal-qadeery6530
      @mohamedal-qadeery6530 ปีที่แล้ว

      When the next parts are going to be relesed ? Cant wait this so amazing

  • @andrewstevens7764
    @andrewstevens7764 ปีที่แล้ว

    Thanks Nick, brilliant timing ive been looking at this pattern for the last couple of weeks

  • @SamueleFurnari
    @SamueleFurnari ปีที่แล้ว +8

    Hi Nick, cool video! Wherever I can (where it doesn't introduce too much overhead), I use mediaR in my projects. Often instead of validating inside the handler, I prefer to define and register in the MediatR pipeline, a class that implements the IPipelineBehavior interface. This also helps me with testability and single responsibility, but I know that some developer hate me for this 😆. In addition to this, I'm making a lot of use of the new publisher to send notifications in parallel (the TaskWhenAllPublisher) which was one of the big limitations of the old versions.

  • @PaulOwens
    @PaulOwens ปีที่แล้ว +36

    I see MediatR implemented a lot but to me it's never clear what problem they were trying to solve.

    • @iliyan-kulishev
      @iliyan-kulishev ปีที่แล้ว +1

      Cross cutting concerns for handlers, pipeline behaviour, that's the biggest advantage imo. It's convenient to have a library helping with that. You don't need MediatR to do CQRS though.

    • @AlgoristHQ
      @AlgoristHQ 9 หลายเดือนก่อน +3

      It doesn't solve any real problems.

    • @artfulperch
      @artfulperch 6 หลายเดือนก่อน +1

      Jimmy Bogard explains the roots of MediatR in this talk - link with timestamp th-cam.com/video/SUiWfhAhgQw/w-d-xo.html&si=wLLdqgW0S5MM9rEh - and it does make sense considering the architecture he describes.

    • @IldarIsm
      @IldarIsm 6 หลายเดือนก่อน

      Nick answers at 3:15 The reason is not to couple horizontally different services and avoid dependency sharing and its creation when it is not even used.

  • @arthurnamu5770
    @arthurnamu5770 ปีที่แล้ว

    Absolute gold nick.. Many thanks

  • @pawenowak5144
    @pawenowak5144 ปีที่แล้ว +2

    Thanks for demo. It's still not clear for me - what if two handlers have a part of code almost or exactly the same? You will put them in some sort of service anyway?

  • @mykhailokozlov6641
    @mykhailokozlov6641 ปีที่แล้ว +7

    This solution looks very nice when working with "todo" apps. However it'd be nice to look at more complex solutions where it's not only CRUD operations but also real business logic and with real code reuse and other things.

    • @okharev8114
      @okharev8114 10 หลายเดือนก่อน +3

      it's the purpose of this approach, the more complex the application, the more decoupling you need

  • @brianm1864
    @brianm1864 ปีที่แล้ว +1

    Been using MediatR for a while now and would love to see more videos on it! Keep up the great work Nick!

  • @alanthomenson3818
    @alanthomenson3818 ปีที่แล้ว +8

    Yeah, I am using this approach for quite a time by now and have no regrets. However, more and more people apparently do complain about MediatR but without any details what's exactly so unwanted there. Therefore, apart from "increased number of files" argument mentioned in video, is there any other drawback of using MediatR?

    • @nickchapsas
      @nickchapsas  ปีที่แล้ว +13

      I am planning to make a video addressing the criticism because in some cases it is valid. It mostly revolves around "you don’t need this" and I agree in most cases

    • @PelFox
      @PelFox ปีที่แล้ว +1

      @@nickchapsas Often you say that and then later you are sitting there with this massive code base without structure and wishing you had started with MediatR anyway :p

  • @mikehkg
    @mikehkg ปีที่แล้ว +10

    The code looks crispy 🎉 but would be interesting to know as you said how to eliminate memory pressure. We already have controllers created per every request. Now we add handlers. All those short living objects will need to be collected. Still I believe that initial singleton service would work faster, due to that it’s already available to process requests.

    • @nickchapsas
      @nickchapsas  ปีที่แล้ว +12

      What a great suggestion! I will add a performance/optimisation video in the series

    • @o5_25kuhen4ik
      @o5_25kuhen4ik ปีที่แล้ว +2

      Correct me if I'm wrong please, but how does it differ from services that are most of the times not singletons but are scoped instances (and the same applies to repositories). So basically we create them for each request too?

    • @rasimismatulin1400
      @rasimismatulin1400 ปีที่แล้ว

      ​@Олег Ляшук yes, if service reg9stered as scoped, it will create a new instance of object for each request. In other words in each request scope it singleton

    • @o5_25kuhen4ik
      @o5_25kuhen4ik ปีที่แล้ว +1

      @@rasimismatulin1400 I see, thank you. Then it will be pretty interesting to see some ways how to avoid this "memory pressure" considering that fact that you can't have singleton repositories

    • @alexanderpoplooukhin7448
      @alexanderpoplooukhin7448 ปีที่แล้ว +1

      Single instsnce of request handler? I think this solution won't work, because you will get singleton instance of repository with single instance of db context for all requests.

  • @bulgarian388
    @bulgarian388 ปีที่แล้ว +37

    I'll throw in my two cents too... I've been using MediatR for around 7 years now. Maybe more... It really helped me to unclog development of an in-house project I had been running for a few years before that where I trapped myself into a maintenance nightmare. A few points I want to make about the video:
    - First, I would simplify the structure because it's too verbose for my taste. For example, you're in the "Movies" feature, so it's pointless to call the create file "CreateMovie", just call it "Create".
    - The repository is a waste. I spent a lot of time years ago trying to understand and use it, but it never stuck. In the end I threw it away, used Entity Framework directly and moved on with my life never to think of repositories again. There truly is no benefit to repositories, just extra code and overhead.
    - The debugging "issue" I don't see as an issue at all. It's just the reality of the code. Granted I could be missing the point of needing to debug into the MediatR methods? From my point of view it's irrelevant since you already know what's going in and what is receiving it, and that's what you should be debugging into.
    - You can model bind directly to the command instead of having an intermediary object to model bind to and then map to the command to pass to MediatR.
    I've also settled on my own structural pattern, which I'll example below for anyone interested. This is what I use in the project I mentioned above, which is on ASP.NET "Classic" on .NET Framework 4.8 and on a side project that's was recently updated to ASP.NET Core 6. My example is from the point-of-view of an MVC app with a UI. Who knows, it may be wildly wrong, but it's served me well for many years.
    public sealed class Create {
    // Command, if needed
    public sealed class Command :
    IRequest {
    }
    private sealed class CommandHandler :
    IRequestHandler {
    // Handle() {...}
    // Private query methods for pulling in data to complete the command,
    // if needed, using Entity Framework Plus future queries and AutoMapper
    // projections.
    // Private utility methods for building up objects, or performing
    // external API calls, or whatever else that's not data retrieval related.
    }
    public sealed class CommandValidator :
    AbstractValidator {
    }
    // Query, if needed.
    public sealed class Query :
    IRequest {
    public Command? Movie { get; init; }
    }
    private sealed class QueryHandler :
    IRequestHandler {
    // Handle() {...}
    // Private query methods for pulling in data to complete the query,
    // if needed, using Entity Framework Plus future queries and AutoMapper
    // projections.
    }
    public sealed class QueryResponse {
    public Command? Movie { get; init; }
    public IEnumerable Tags { get; init; } = Enumerable.Empty();
    public sealed class MovieTag_ {
    public string Name { get; init; }
    public string Slug { get; init; }
    }
    }
    // Hangfire background job, if needed.
    public sealed class Job {
    }
    private sealed class JobHandler :
    IAsyncJob {
    }
    public static string Enqueue(
    Job job) {
    var handler = new JobHandler();
    return handler.Enqueue(job);
    }
    // AutoMapper profile, if needed.
    private sealed class Mappings :
    AutoMapper.Profile {
    public Mappings() {
    CreateMap();
    CreateProjection();
    CreateProjection();
    }
    }
    }
    In case I'm coming off as critical, that's not my intent, just wanted to share my experience. I've learned quite a bit from you since I discovered you ~2-3 years ago, so thank you for sharing your knowledge!

    • @AlexMercer00
      @AlexMercer00 ปีที่แล้ว +4

      If you use EF directly then Movie class can/is able to access directly other Tables that is not related to Movie. By having a repository it is also more readable by just looking at the depedencies that this class is only dealing with Movie data.

    • @nicksteffen8720
      @nicksteffen8720 ปีที่แล้ว

      @@AlexMercer00 Your restricting access at the service layer instead of the repository one. If you must, you can use the dbset instead of the whole context if your worried about accessing other tables. so instead of injecting DbContext you inject dBset. Then you just gotta call save from somewhere. Unless you are exposing your repository later to another group or team you don't really trust i don't think restricting access is really a benefit though certainly not one worth all the extra code. You can also create a context for each set of tables you want on object to have access to if you really want to repositorify ef Core. You still gain a lot of benefit from the linq syntax so maybe thats worth it.
      I would say the reason its more readable is that there is a lack of purpose because you often have one method called create just calling another method named create. Its readable sure, but it doesn't do any work.
      I would also add that its much easier to unit test against a mocked dbcontext as you just add a list of test objects to a real dbset, plug into a mocked context and all of the methods work as normal intead of mocking each method in a repo pattern.2:22 AM 4/26/2023

    • @Denominus
      @Denominus ปีที่แล้ว +9

      The whole Movie/CreateMovie (anti)pattern actually has a name, its called name stuttering.
      eg. Thing.ThingLoader.LoadThing()

    • @francismarasigan108
      @francismarasigan108 ปีที่แล้ว +5

      For what I read repository is actually anti-pattern for EF. Note for EF only! Repository is still valid for other db provider. DbSet is actually a equivalent of repository and DbContext can provide you the UnitOfWork equivalent in Repository pattern. So overall if you are using EF, repository is just redundant and extra code and doesn't really serve much benefits in EF.

    • @slowjocrow6451
      @slowjocrow6451 ปีที่แล้ว

      I'd be very interested seeing a mini github project using your way if you happen to have one? I love the idea of mediatr/cqrs/vertical-slice but finding online examples too verbose and struggling to justify it

  • @nicolasrey3383
    @nicolasrey3383 ปีที่แล้ว +2

    It could be also a good idea to talk about unit testing and/or integration testing using mediatr

    • @MrHeavyRunner
      @MrHeavyRunner ปีที่แล้ว +1

      Exactly. This part is sorely missing.

    • @rzaip
      @rzaip ปีที่แล้ว

      You integrationtest your handlers by sending requests or you may run them as any other integration test through calling the API.
      But if you don't care about the API layer you can test the handlers directly as I mentioned above.

  • @jonathanperis3600
    @jonathanperis3600 ปีที่แล้ว +2

    Nick you did a video regarding Mediator and it's benefits. Source generator, ready for AOT, parity with Mediatr. Why not continue to use it as example for mediator pattern?

  • @Forshen
    @Forshen ปีที่แล้ว +2

    Hi, i don't get the concept of the Request and the handler of it. Cause Mediatr has the Send function, passing a object, and 1 handler for handling that object. But why it is better compared to just calling a command/query Handle() directly (with some adjustments of course)? I hear a lot of 'decoupling' but that is a very generic answer to me. I am reading and watching videos about Mediatr. One part want to try it, but other side. It doesnt feel as an improvement. The INotification in Mediatr is a different story tho.

  • @hemant-sathe
    @hemant-sathe ปีที่แล้ว +1

    My experience is that it’s an excellent way to implement security. Most of the security is on what you can and can’t do (except may be which fields you can read). Mediator works great for action/command based security. It eases the load of implementing authorisation to a great extent.

    • @kabal911
      @kabal911 ปีที่แล้ว +1

      Yeah, it’s awesome. I use source generators to create permissions for every query/command.
      Also also use source generators to create controllers/endpoints for every query/command (unless explicitly excluded), which make use of these permissions.
      Super easy to build up Admin UI to manage the permission assignment (against roles or users or whatever model you use)
      Then it just all works transparently using .Net authorization

    • @hemant-sathe
      @hemant-sathe ปีที่แล้ว +2

      @@kabal911 would love to get details of your approach to code generators. In case if you have any blog post or github repo, please share. I use the Jason Taylor's clean architecture template and have taken out some common code as packages but there is still a lot of repetitive code that would be fun to move to code gen.

  • @cinosz6780
    @cinosz6780 ปีที่แล้ว +1

    Hi Nick and others, can someone explain what the "contracts" folder is. Is this another way of defining a DTO?

    • @torrvic1156
      @torrvic1156 11 หลายเดือนก่อน +1

      I think those are the interfaces.

  • @petrucervac8726
    @petrucervac8726 ปีที่แล้ว +14

    The reduced debugging experience is a real problem, especially when fixing live issues

    • @nickchapsas
      @nickchapsas  ปีที่แล้ว +21

      I’ve been thinking for the longest time to make a Rider plug-in which discovers the handler and automatically steps into the right handle method

    • @nicolasrey3383
      @nicolasrey3383 ปีที่แล้ว +9

      Placing both command and handler in the same file is a workaround. From controller you click on the command that makes you jump on the handler file as well

    • @weluvmusicz
      @weluvmusicz ปีที่แล้ว

      @@dolgodvorovn In need this for vscode :D

    • @Elephantine
      @Elephantine ปีที่แล้ว +1

      @@nickchapsas
      using Rider, when you have cursor on a command class name, you can use Navigate to , then Consuming APIs to navigate to the handler., but is no way to make direct shortcut to Consuming APIs :(

    • @andriihorbokon2015
      @andriihorbokon2015 ปีที่แล้ว +1

      @@Elephantine You can make shortcut yourself, very useful

  • @mohamedal-qadeery6530
    @mohamedal-qadeery6530 ปีที่แล้ว +2

    u said this first video of 3 parts where is the remaining parts ? great video btw

  • @Durovv
    @Durovv ปีที่แล้ว +1

    Nice, you show a good architecture idea. I use MediatR library in my project and I don't regret about it. I'll be waiting new parts of this trilogy. 😄
    You are the coolest programmer that I know)
    Keep coding!

  • @MrMaksuz
    @MrMaksuz 3 หลายเดือนก่อน

    great video! Thanks

  • @khwezimngoma
    @khwezimngoma ปีที่แล้ว +1

    @Nick Chapsas, you are the guy that showed me the value of using CQRS through Mediatr, i am curious what you think of Wolverine? lol not the Marvel character, but the library rival of Mediatr.

  • @Zisane21
    @Zisane21 ปีที่แล้ว

    Nick, what about a video on Result to describe how to return error instead of throwing exceptions from any layer?

    • @Eriksonlove69
      @Eriksonlove69 ปีที่แล้ว

      I hope this can help you.
      th-cam.com/video/YbuSuSpzee4/w-d-xo.html

  • @michaelaanraad7916
    @michaelaanraad7916 10 หลายเดือนก่อน

    Next video never came out? :) Don't see any link? Cheers

  • @MohammadKomaei
    @MohammadKomaei ปีที่แล้ว +1

    If we have a query that join 3 tables in it, which feature do you choose for writing the query?

    • @iliyan-kulishev
      @iliyan-kulishev ปีที่แล้ว

      What is the business meaning ? You don't just "read products", "read students, including the grades" etc. Think in terms of business capabilities and not data persistence entity models.

  • @AayushRastogiKnowMe
    @AayushRastogiKnowMe ปีที่แล้ว +1

    Can we use MediatR when using FastEndpoints ? FastEndpoints also are based on vertical slicing. Will that be just an overhead ?

    • @nickchapsas
      @nickchapsas  ปีที่แล้ว +1

      You can totally use FastEndpoints to do the same thing

  • @nthonymiller
    @nthonymiller ปีที่แล้ว +3

    I personally love MediatR and CQRS pattern, as each command and query does exactly one thing, easy to locate logic.

  • @wilmararias2083
    @wilmararias2083 ปีที่แล้ว

    Hi a found a post on stack overflow : Entity Framework async operation takes ten times as long to complete vs non async.
    Can you make a video that describes this issue and what is the best practice or work around when working with EF and async operations? Thanks 🙏

  • @SrabanNadimulIslamBhuyan
    @SrabanNadimulIslamBhuyan ปีที่แล้ว

    is virticle slice architecture is good for large application, I mean thousand of table?

  • @orthodox-4-ever
    @orthodox-4-ever ปีที่แล้ว +1

    What are the differences between Result and OneOf? Which one you prefer?

  • @JustMe-gp4so
    @JustMe-gp4so ปีที่แล้ว +1

    Hey, Nick, check 'OneOf' package.
    You could replace your generic Result class and simplify idorslug parameter, i think code will be more readable and interesting to write =)

    • @francismarasigan108
      @francismarasigan108 ปีที่แล้ว

      He already use it on one of his old video : th-cam.com/video/r7QUivYMS3Q/w-d-xo.html

  • @petrblaha703
    @petrblaha703 ปีที่แล้ว +1

    Are there any advantages to using Command/Query handlers specificly instead of Request handlers?

    • @necrokora7688
      @necrokora7688 ปีที่แล้ว +2

      Primarily Intent. It is easier to know what is intended by the developer if the developer wrote down the intent explicitly. Aside from that, you can actually use some mediatr features to segregate between both if you know how - but I imagine Nick will do a video about that. It is useful if you have concerns that apply to transformative requests but not to pure queries or the other way around (like tracing maybe?)

  • @MoussaSoliman
    @MoussaSoliman 6 หลายเดือนก่อน

    Thank you

  • @jakobaaredam6589
    @jakobaaredam6589 ปีที่แล้ว

    Thanks for the video. Why not split up the existing service instead, avoiding the pains you mentioned ? But, maybe I’ll get the point in the coming up ‘supercharge the api’ video😊

  • @RamiroPuentes-q6x
    @RamiroPuentes-q6x ปีที่แล้ว

    Can you share you process for Penetration testing web applications?

  • @mp_petrov
    @mp_petrov ปีที่แล้ว +3

    @Nick Chapsas I’ve seen my colleagues putting the IRequest and the Handler classes in a single file, this way you can easily step into the handler when debugging as it goes to create a “command” for example and the handler is right there waiting for you. :)
    Even if you have separation between presentation and application layers, you can argue the IRequest classes are part of the way the Application layer works and they can stay in the same file.

    • @kabal911
      @kabal911 ปีที่แล้ว +1

      Yeah, debugging has literally never been an issue for me, because you can just “go to implementation” on the command/query and end up at the handler.

    • @pioners1001
      @pioners1001 ปีที่แล้ว +1

      I'm doing the same - keeping everything in one file. Although, I am creating a static wrapper class with Command/Query and Handler in it. The name of the static class is the name of the action that is going to be handled and I have generic Command or Query and Handler for names within it.

    • @kabal911
      @kabal911 ปีที่แล้ว

      @@pioners1001 I make my command/query the “wrapper”, with the handler, mapper and validator as classes inside

    • @StuartQuinn
      @StuartQuinn ปีที่แล้ว

      What's the benefit of a wrapper?

    • @torrvic1156
      @torrvic1156 10 หลายเดือนก่อน

      It looks horrible! Why bundle everything in one class. I just don’t get it.

  • @mohamedelhakim5966
    @mohamedelhakim5966 ปีที่แล้ว

    I have used mediator in many projects but many people miss the big picture, you can benefit from event dispatching,pipelines in workflow and helps in making DDD much easier

  • @derm4525
    @derm4525 ปีที่แล้ว +1

    What are the benefits of using Mediatr here over, for example, simply having separate classes & interfaces for these concerns?
    I see that in a controller which has it’s endpoints grouped under one controller may have then multiple dependencies to inject, but using a minimal API approach would mean that each endpoint will only inject the dependencies you need which effectively resolves that issue.
    What are your thoughts on this?

    • @nickchapsas
      @nickchapsas  ปีที่แล้ว +1

      Like I said in the video, if you look at this in isolation, then you didn't gain much. The two followup videos will make the benefit way more clear. This video needed to be standalone because many people are interested in the "how to get started".

    • @kabal911
      @kabal911 ปีที่แล้ว

      Baked in patterns for 1.
      No need to implement glue.
      Pipelines/behaviors.
      Documented by someone else.
      Consistency between projects/teams.

  • @22pager
    @22pager ปีที่แล้ว

    What do you think about using Command and Query classes as a contact?

    • @nickchapsas
      @nickchapsas  ปีที่แล้ว

      It could work but the problem is that your application layer knows about your api contract which can be problematic

  • @hassejansson
    @hassejansson ปีที่แล้ว

    why don't validate earlier, in the controller method?

    • @nickchapsas
      @nickchapsas  ปีที่แล้ว

      Because the controller isn't supposed to know how the domain object should be validated. We gonna more that where it belongs in the 3rd video of the series

  • @kabal911
    @kabal911 ปีที่แล้ว

    Kind of related to MediatR, but more a property of Vertical Slice architecture, is that I have anecdotally noticed a drastic reduction in regressions. Obviously it is hard for me to quantify this, as I can only compare previous projects to recent projects, but to me it makes sense.
    When you are “sharing” code in services, just because they happen to look the same, it is inevitable that a change to accommodate 1 area might affect another.

    • @MrHeavyRunner
      @MrHeavyRunner ปีที่แล้ว

      So do not share the code? No need for Mediatr. The problem lies in how you wrote the code. No library can solve that.

    • @kabal911
      @kabal911 ปีที่แล้ว

      @@MrHeavyRunner of course we have shared code. I also specifically said this was nothing to do with any library

  • @patrykorlowski3285
    @patrykorlowski3285 ปีที่แล้ว

    Would be interesting to see your take on cqrs with event sourcing using something like marten or eventstoredb maybe even wolverine to see some other mediator implementation that the plain old mediatr

  • @nonamezz20
    @nonamezz20 ปีที่แล้ว

    In regards to mapping. Does it make any sense to extend a class that you already own ? I can see it is used as syntactic sugar but it doesn’t make sense in my opinion.

  • @MarusykRoman
    @MarusykRoman ปีที่แล้ว

    what if "feature/slice" depends on another feature? how then do you organize the structure?

  • @lil_nach
    @lil_nach ปีที่แล้ว

    Have you heard of MassTransit? I would be really curious what your thoughts are on it

  • @luvincste
    @luvincste ปีที่แล้ว +1

    is this going in the direction of an actor model approach, because if not then what's the reasoning behind this

    • @nickchapsas
      @nickchapsas  ปีที่แล้ว

      I guess you'll have to wait and see in the future videos

  • @nilpunch2
    @nilpunch2 ปีที่แล้ว +4

    So, the main benefit of using MediatR is to decompose dependencies and logic from controller into their own files and handlers and whatever. So, there is no godlike controller.
    The question is: why not just do this decomposition by defining appropriate interfaces and classes for each command/query handlers, and then pass them as dependencies to the controller? This is straight as hell, and all business logic and validations can have their place under realization details of these handlers.
    What I can see, is that with MediatR these dependencies just obscured with a single dependency of MediatR itself, that has method "Process anything, please".
    Using MediatR feels kinda redundant, and it has consequences of been obscured and hard to debug.

    • @gileee
      @gileee ปีที่แล้ว +3

      I'm of the same opinion. I saw a comment on this video how using MediatR specifically becomes beneficial when you add behaviors or pipelines. Which to me look like the same old middleware pattern I've been using in Node for years without issue and without any kind of a Command -> Handler mapper.
      Nick also mentioned cross cutting concerns, but I've never had issues with adding them into the chain.
      So personally I'm more inclined to go with the same architecture where I'd have /movies/[Service, Repo].cs and then /movies/create/[Request, Response, RequestValidator, Endpoint...].cs. In Node I additionally don't even have a repo since prisma is so damn good and the "services" are also separated into the individual domains just for cleanliness if nothing else.
      Additionally if my API doesn't need OpenAPI support (is only made to service one frontend) then I just use something like tRPC which removes the need for Request and Response objects completely.
      Less code, fewer files, less dependencies and being more explicit is always better imo.

    • @bodek321
      @bodek321 ปีที่แล้ว +3

      +1 from me! I work in a project where MediatR is widely used and IMHO overused. In 90+% cases I don't see many advantages over the classic decomposition by defining interfaces. My team is now in process of the removing MediatR's Handlers, many of them are just hard to defend burden. There are only rare cases where MediatR is demonstrating the positive impact on the code.
      I have to mentioned the dark side of the MediatR. In my projects there was era of developers who used MediatR's commands as the contracts in API, beautifully mixing the concerns, as Nick mentioned bellow. I know that it's discouraged and known as a bad pattern, but looks as a tempting and lazy solution

    • @kabal911
      @kabal911 ปีที่แล้ว

      “Bad”, “lazy”, “mixing concerns”- according to some arbitrary rules.
      I’ve had huge success with multiple projects and teams in using source generators to generate endpoints based on queries/commands.

    • @bodek321
      @bodek321 ปีที่แล้ว +1

      @@kabal911 Agree, that was too overgeneralization. I personally see it as a bad pattern and my team is trying discourage juniors not to apply it in the codebase. I believe it could be successful especially when API are really micro and are very specialized. My project is very far from that point

    • @kabal911
      @kabal911 ปีที่แล้ว

      @@bodek321 👍🏻the best solution is always the one that works for the team. Consistency is key. I run a software consultancy, so for our teams to be able to deliver the “same” architecture across multiple projects is a big plus.

  • @juke-duke
    @juke-duke ปีที่แล้ว +1

    GraphQL + Vertical Slice Series Paaaaleaaasssseeeee

  • @paulomonteiro1165
    @paulomonteiro1165 ปีที่แล้ว

    What about Wolverine? I recently watched something from Anton at Raw Coding and it looked promessing. Any opinion on that?

  • @sgelagaev
    @sgelagaev ปีที่แล้ว

    Why don't you use extensions for validation requests?

  • @jon-slem
    @jon-slem ปีที่แล้ว

    Vertical Slice is really cool. I've never use it. I'm still using Clean Architecture. My questions here is, since everything seems locked down to a feature, how do one feature communicate with another besided through the controller? If not then a feature is physically calling another feature's handler directly. if that's the case why not just go with Clean Architecture? For simpe CRUD as you showed here it's great until you have a more sophisticted application it seems

  • @Bourn77
    @Bourn77 ปีที่แล้ว

    Hi Nick, helpful video as always, I found your usage of Results for response from a class intriguing, since we don't have proper discriminated unions in C# , this will be helpful in cleaning up my service classes without Early reruns or Exceptions to control the flow. can this be used in Production apps? i currently work with Clean architecture project with Controller/Service/Repo layers, i found using early returns for control flow to be cluttering my code base, too many reruns in service/repo layers. Can you make a video on how to properly implement control flow in such a case? and how to setup the Results pattern in an api project?

  • @BrokoIis
    @BrokoIis ปีที่แล้ว

    I assume you are going to move validation to pipeline behaviors. It's a nice way to implement it, except that the request object is not the API contract object/model. Which means that validation errors might not match the contract. How do you deal with that?

    • @BrokoIis
      @BrokoIis ปีที่แล้ว

      I myself do basic validation (like max length, nulls, file size, etc...) on the contract models, and don't validate the commands/queries at all, since after validating contract models they are mapped to queries/commands.

  • @nanvlad
    @nanvlad ปีที่แล้ว +1

    Does anybody know if there is some extension or code analyzer which helps to create and navigate between Command/Request and Handler? When system grows it becomes too hard to add a new query/queryhandler in corresponding folders

    • @PelFox
      @PelFox ปีที่แล้ว

      You can create your own code snippers/templates.

  • @vklooping
    @vklooping ปีที่แล้ว +3

    Good video, although MediatR can be really handy with Blazor server side and could fit better into this video and give another insight on its usage since components are long-lived and MeidatR can also have its purpose for simulating that "scoped" service lifetime for actions on the page since we don't have http requests and responses.

  • @furt
    @furt ปีที่แล้ว +2

    Hi Nick! Great video as always!
    Our company bought your testing courses for a few of our developers.
    We really enjoyed and it would be awesome if you could add examples on how to test the application using mediatr and using DbContext directly instead of repositories. As we tend to divide our features with queries, we don't see the need to use repositories anymore.
    Also, why show examples using Mediatr instead of Mediator package from martinothamar? We started using that package since your video recommending it and we're loving it.
    If you're looking for video suggestions, it would be great to see how you would organize a lambda project with shared projects.
    I'm looking forward for the rest of the series!

  • @vertigosoft
    @vertigosoft ปีที่แล้ว

    this is exactly the pattern I use.

  • @istovall2624
    @istovall2624 ปีที่แล้ว

    using medatir i created a generic base controller method that handles the dto => command, and command response => dto mapping, i also i put my validator lookup and validation inside the method so all my controller is doing is calling that method and explicitly declaring the conversion types. Any comments on that being a good/bad implementation? saves me tons of code :D

    • @kabal911
      @kabal911 ปีที่แล้ว +1

      I do similar. Except I use source generators to create endpoints. No need to do any mapping from dto to command/query. The command/query is the request dto. The command response is the http response object.
      OOP people will hate this, as it “violates” arbitrary “rules.
      Our teams love it because they get to write and maintain less code.
      Because we are then generating API clients for typescript, changing your command/query will instantly feedback to you in the TS/JS pipeline.

    • @kabal911
      @kabal911 ปีที่แล้ว +1

      I’ve also introduced IQuery, ICommand and ICommand.
      This gives us consistent responses. Implement using these interfaces, specify the base result type, but the actual result type is ErrorOr.
      Less code, less thinking about what, and more building value

    • @istovall2624
      @istovall2624 ปีที่แล้ว +1

      @@kabal911 yea same, i only did it in my personal project so far, but i love it. so much less code, only need to write what goes in the handler. i also implemented generics, i have an ISearchable and IPageable, and ICommandResponse that will inherits one or the other or both as needed.

  • @buriedstpatrick2294
    @buriedstpatrick2294 ปีที่แล้ว +3

    I've been using MediatR for years and it's just my default way of implementing anything these days. Although not shown here, it really comes together once you start working with pipelines and split your code into feature-projects. It's essentially taking the principle of "composition over inheritance" and applying it to your entire architecture. I can understand it might not be suitable for very performance-sensitive applications, but I have never found MediatR to be the bottleneck if I'm having issues there.
    Also, I often hear the argument that it's another level of indirection, like in your example with the debugger. But if you stop to think about it, it's really not that different from what we're doing when we inject services via their interface. You don't really necessarily have a 1-1 relationship between an interface and its implementation either. Yet, most of the time this IS the case, and so the "indirection" is a really weak criticism because you can easily navigate to a handler-implementation that references the request, especially if you structure your project properly (which you should always be doing anyways).
    Furthermore, the vertical slice approach lets you quickly test and create new applications that re-use existing code in a very "off the shelf" way if you do it right. Say you want to add a movie via a command-line app as well. You just have your Movies library as a feature-project and register it with MediatR the same way. All the logic is packaged neatly in the library and will work in the exact same way.

  • @swstein
    @swstein ปีที่แล้ว

    The projects I've worked in that used mediatr, it added nothing but complexity and code mis-direction. Realky don't get what the point of it is.

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

    where is the source code link ?

  • @psyarhei
    @psyarhei ปีที่แล้ว

    Why don't just not to inject a validator to a method which requires it?

  • @nicolasrey3383
    @nicolasrey3383 ปีที่แล้ว +1

    Btw this is an old debate but what can be seen as a problem is that the commands or events have to be marked with Mediatr interface which put a high coupling between our app and this lib,this sounds like impedance mismatch and the effort to decouple from an abstraction layer does not worth it imo

  • @ovide115
    @ovide115 ปีที่แล้ว

    Great video, but what I think is a bit bizarre (and I have seen it a lot as well and do not yet have a real opinion on it yet...(Don't know if I need one but curious about yours :) )) is you are mapping requests in one ore multiple controllers to command's and queries, thus splitting up the work to call again one or multiple big (read or write) repositories containing the implementation off big parts off the actual work. I know that command's can and mostly do encapsulate a lot more work then just writing to a database.... So I absolutely see the benefits. But especially in this example you create a one (controller/endpoint) to many(queries and commands) to one relationship(reposository), and especially for the query part of the story I do not see the benefit off just referencing (an abstraction of the) read repository in the controller... Greetings, thanks for the great work keep them coming please. Thanks

  • @Ricks_Shorts
    @Ricks_Shorts ปีที่แล้ว +4

    Looks messy! Not seen the other videos yet, but this first one doesn't sell the use of MediatR to me at all.

  • @hkoueke
    @hkoueke ปีที่แล้ว

    Nike Chapsas 😁

  • @lordicemaniac
    @lordicemaniac ปีที่แล้ว +6

    the criticism of mediator is only right in projects which use mediatr just as glorified service locator like currently in this project, I guess when you continue this series, you will move validation into behavior and maybe do some more things (i am very curious what else you will show), then whole criticism looses point

    • @nickchapsas
      @nickchapsas  ปีที่แล้ว +5

      That’s exactly what the next two videos are. Validation and cross cutting concern implementation 😃

  • @DmitryV_HF
    @DmitryV_HF ปีที่แล้ว

    Simple models - brilliance code. What about models with diffrerent data? Example, movie can have rating, urls, actor lists, comments and etc. Do you save one big model with dependency properties, or run different commands on each "sub-object" ?
    What about situation, when need run few commands on one transaction? Run all commands by order into service? or from handler?
    Never saw recomendation for real working situations. ;)

  • @camelpilot
    @camelpilot ปีที่แล้ว +1

    MediatR is only worth using if you find yourself injecting a lot of dependencies and services. If you are just injecting 1 service, and that service encompasses everything related to that service, nothing more, nothing less, then it is BETTER to have everything in 1 place. 1 file. No need to run around like a chicken with its head cut off, pretending to prepare for a scenario that will never happen. When you find that your Service/Repo pattern doesn't do the job, only then should you explore MediatR pattern. Using it any other time will be an unnecessary maintenance nightmare, especially for areas of the app that don't even need it.

  • @RaviYadav-bt2eg
    @RaviYadav-bt2eg ปีที่แล้ว

    Thanks for this amazing series around Mediatr. I have been using it myself in many projects and I also feel the same as others about the criticism it gets so really looking forward to upcoming vids. I just had one request, can you also compare it with some other alternative like Wolverine, etc with respect to Coding practice and performance.

  • @botondvasvari5758
    @botondvasvari5758 11 หลายเดือนก่อน

    I don't see why Movies or Catalog etc. are features, they are domain models. Features would be WatchMovie, DumpCart etc.

  • @felipesuarez6564
    @felipesuarez6564 ปีที่แล้ว

    Sorry I'm still not sold on this MediatR approach yet. The first version of your code looked awesome to me already :)
    The debugging problem is a huge one, but what I find as the real problem is the explosion of files. What is the difference between having one big file full of spaghetti code vs having hundreds of files with very little amount of code in each (and a lot of boilerplate)? I find both approaches to be bad.
    I think the controllers/services/repository approach is a good middle ground between spaghetti and explosion of files/boilerplate.

    • @herbramos3985
      @herbramos3985 ปีที่แล้ว

      The problem with on big file full of spaghetti code is just that - full of spaghetti code and hard to manage. Imagine a service class that had 30 methods and 4000 lines of code. If multiple devs work on this service at the same time (very likely), you increase merge conflicts. Think about applying the "Single Responsibilty Principle" and make your classes small. Smaller classes reduce your conflicts and can be very specific to a business use case. They are also better for unit testing. This is a beautiful thing IMO.

    • @felipesuarez6564
      @felipesuarez6564 ปีที่แล้ว

      @@herbramos3985 of course, but I think you misunderstood my comment. I am not advocating for writing everything in a single service file, but rather have many services through your application. I still think MediatR is bad and pray that I don't need to work in projects using this approach in the future

  • @alexanderpoplooukhin7448
    @alexanderpoplooukhin7448 ปีที่แล้ว +1

    Thank you Nick. It's very cool video. MediatR and Commands pattern approach are very suitable for anemic model with very simple business rules, and you get lesser benefits in case of using mediatR with rich model. Isn't it?

  • @xXxRK0xXx
    @xXxRK0xXx 3 หลายเดือนก่อน

    Tightly coupling with 3rd party packages. Amazing!

  • @torrvic1156
    @torrvic1156 10 หลายเดือนก่อน

    This bundling up almost everything in one file looks horrific honestly. It must be pretty hard to test it and I guess we should forget about SOLID.

  • @ArturMichajluk
    @ArturMichajluk ปีที่แล้ว

    Wow, the 100th like :D

  • @SecondFinale
    @SecondFinale ปีที่แล้ว +1

    MediatR feels a little fishy to me, similar to most DI libraries where it's hard to find a convincing article on why it's better than just good coding practices. Proponents are enthusiastic and I can't tell if it's founded.

    • @kabal911
      @kabal911 ปีที่แล้ว

      I can certainly say that in every project is have implemented this pattern, and in every team, we have not forsaken “good programming practices”

  • @jackiedaytona1017
    @jackiedaytona1017 ปีที่แล้ว +3

    I was more of a fan of Nick the Greek 2, 3 was where they jumped the shark. I can’t believe the ending was, ‘it was all a GPT hallucination this entire time.’ SMH

  • @weluvmusicz
    @weluvmusicz ปีที่แล้ว

    Just use services and call the child by its name.

  • @0x4b55
    @0x4b55 ปีที่แล้ว

    One More Year (or two) of Hardware Improvement is absorbed by a Software Abstraction Layer. You Know the Hardware Guys hate you

  • @GigAHerZ64
    @GigAHerZ64 ปีที่แล้ว +2

    Mediatr (and other such libraries) is just a glorified ServiceCollection/DiC.
    Prove me wrong.
    CQRS and vertical slices don't require any additional libraries.

  • @jakubsutak8471
    @jakubsutak8471 ปีที่แล้ว +1

    Hey, guys. I can't remember the name of the library that Nick uses to handle the output of the Create action on the controller:
    result.Match
    (m=> CreatedAtAction(....),
    failed => ...)
    Someone write me the name of it ... thanks a lot

    • @silkfire
      @silkfire ปีที่แล้ว +1

      That's OneOf

  • @petrucervac8726
    @petrucervac8726 ปีที่แล้ว +5

    MediatR looks like a glorified service locator

    • @nickchapsas
      @nickchapsas  ปีที่แล้ว +5

      I very much disagree. That’s a very epidermic statement that probably deserves its own video.

    • @diegopego1069
      @diegopego1069 ปีที่แล้ว +1

      ​@@nickchapsasplease, do it!

    • @petrucervac8726
      @petrucervac8726 ปีที่แล้ว

      @@nickchapsas well, you insert in your service mediator which you then use to send commands and queries to any other service in your application. This doesn't sound like a good approach for most use cases

    • @ravikumarmistry
      @ravikumarmistry ปีที่แล้ว

      So true

  • @jp2code
    @jp2code ปีที่แล้ว

    Your video was way too fast for me to follow

  • @aristideherve5748
    @aristideherve5748 ปีที่แล้ว

    I'm the first!

  • @ib0018
    @ib0018 ปีที่แล้ว

    This makes no sense. Also its hard to find the file.

    • @nickchapsas
      @nickchapsas  ปีที่แล้ว +2

      I would say it is way more discoverable than what it was before. Everyhing regarding one feature is in a single location.

    • @ib0018
      @ib0018 ปีที่แล้ว

      @@nickchapsas to me it is just looks like outsourcing the inside of a controller. At my job the solution you provided in the video is mandatory to use, but im highly against it. For instance its much harder to find the business logic, because i have to find the command then the handler itself. Also its harder to create abstraction because one handler is basically the aggregate of calling repository functions and contains a full business logic, which cannot be reused in most scenarios. If you build up your project using repository and managers and services pattern, i doubt you need mediatr. What is your opinion about that?