Build Messaging in .NET with Wolverine

Sdílet
Vložit
  • čas přidán 14. 02. 2024
  • Use code MODULAR and get 20% off the brand new "Getting Started with Modular Monoliths" course on Dometrain: dometrain.com/course/getting-...
    Get the source code: mailchi.mp/dometrain/p1gsk69m94y
    Become a Patreon and get special perks: / nickchapsas
    Hello, everybody, I'm Nick, and in this video, I will show you how you can get started with messaging in .NET using a Nuget package called Wolverine.
    This video is sponsored by AWS
    Workshops: bit.ly/nickworkshops
    Don't forget to comment, like and subscribe :)
    Social Media:
    Follow me on GitHub: github.com/Elfocrash
    Follow me on Twitter: / nickchapsas
    Connect on LinkedIn: / nick-chapsas
    Keep coding merch: keepcoding.shop
    #csharp #dotnet

Komentáře • 118

  • @baranacikgoz
    @baranacikgoz Před 2 měsíci +38

    Can you do a video about difference between Masstransit and this. From a Masstransit user's perspective, you don't need any queue and exchange configuration at all. It can create all endpoints for you. More streamlined You don't have to explitly tell listen to that queue etc.

  • @liva236muzika
    @liva236muzika Před 2 měsíci +5

    16:35 Transactional Outbox pattern. So glad you talk about it.

  • @VanDameDev
    @VanDameDev Před 2 měsíci +14

    Great timing. I was looking for a video on Wolverine.

  • @EER0000
    @EER0000 Před 2 měsíci +4

    In a previous project we were using Rebus, which I quite enjoyed, I am not sure if the project is still active but I would choose if again any time :)

  • @ahmednehhas9767
    @ahmednehhas9767 Před 2 měsíci +7

    Awesome!
    Eagerly awaiting NServiceBus video🥳

  • @devmarkmonster
    @devmarkmonster Před 2 měsíci +1

    Nice video. I am a fan of MassTransit. It feels a bit more mature, but it’s good there are choices. When looking into the way to implement Sagas in Wolverine, they look very similar to the NServiceBus implementation, though I prefer the state machine Sagas of MassTransit. Keep these videos coming. 👌🏻

  • @g3org3ir
    @g3org3ir Před 2 měsíci

    Look nice, thanks for sharing this!

  • @klocugh12
    @klocugh12 Před 2 měsíci +9

    I kind of wanna watch that "Nick the Great" comedy 😅

  • @cdarrigo
    @cdarrigo Před 2 měsíci +7

    This looks like a neat package. Although I don't like the fact that the messaging configuration for the individual messages is abstracted away from the message contract. This creates some fragility in the solution as both the sender and receiver of the message need to individually properly configure the queue name to the same queue. I'd much rather be able to decorate my messages with attributes that have that configuration data. That way when I share contract, I'm also sharing the Queue or topic name. I'd also like some designation on the contract whether or not this is intended to dispatch work or a notification. If I'm dispatching work, it's likely to go to a queue, and if I am sending a notification, I am likely to use a pub sub solution.

  • @cdarrigo
    @cdarrigo Před 2 měsíci +23

    I also think the fact that he's embedded his messaging solution with his custom DI is pretty crappy. One not abstracted out so we could choose our own DI provider

    • @tafs7
      @tafs7 Před 2 měsíci +8

      Not trying to say one way is better or crappier, but the author (Jeremy Miller @jeremymiller9966 ) was also the author of StructureMap - the original IOC container for .NET. That project was eventually obsoleted by Lamar, as he created it to be compatible with the .NET Service Provider, faster, and while offering many of the additional features available in StructureMap (e.g., registries, decorators, diagnostics, conventional registration, etc.).
      His choice in using this is probably so he supports convention-based wiring of handlers without using runtime reflection tricks which can be a tad slower. By doing that, and also pushing for a Wolverine best practice approach favoring pure functions and method injection vs. constructor injection (though still supported), he can provide better runtime performance of the Wolverine framework.
      Also worth noting that WolverineFX is part of his broader Critter Stack, which includes Marten for event sourcing with Postgresql.

    • @cdarrigo
      @cdarrigo Před 2 měsíci +10

      @@tafs7 My issue is that he's forcing an implementation of a non-messaging solution in his messaging solution. It should be open to extension.

  • @satyayuga0
    @satyayuga0 Před 2 měsíci +1

    I'm still unsure as to the conventions vs contract thingy.
    On the one hand, I think that not having the bloat of extra Interfaces is pretty neat. Don't have to repeat myself myriads of time.
    On the other hand, it gives me some kind of safety in a way. Since I'm someone who also misspells his own name from time to time, that naming by convention thing is bound to fail here and there from time to time.
    I'm 49 : 51 on this.

  • @phizc
    @phizc Před 2 měsíci +2

    8:18 for most duck typing, I think the method or class should have an attribute. Otherwise what's stopping the messaging system from assuming *all* Handle methods are message handlers?
    The built in ducktyping in C# I know of are Deconstruct, and 'void Dispose(), which makes allows you to use something like
    'using var x = new MyDucktypedDispose()'
    with ref structs, which can't have interfaces. Both of those are to allow language features, not to let some system slurp them up.
    Tldr; unless it's to enable language features, don't use purely duck typing.

  • @heyitsmikey01
    @heyitsmikey01 Před 2 měsíci

    Setup wolverine with azure service bus and it just works. Amazing!

  • @svetoslav.hadzhiivanov
    @svetoslav.hadzhiivanov Před 2 měsíci

    I haven't dived into its source code but it seems to have some aspects of an actor model implementation e.g. remoting, discovery and persistence features. You can also respond to the sender

  • @aboooow
    @aboooow Před 2 měsíci +4

    This is very similar to a library I built not too long ago. The main differences are that I had an attribute on the consumer to indicate it's an event consumer, and also, I didn't replace the entire DI container..

  • @GlebWritesCode
    @GlebWritesCode Před 2 měsíci

    Looks interesting.
    I'd say auto-creation of queues/exchanges is great for dev purposes. When you have many queues, I'd prefer to have separate script that can create all of them - much easier for things like creating a new environment (e.g. for load testing)

  • @charlesaboujawdeh
    @charlesaboujawdeh Před 2 měsíci

    Hey I really find your videos and insight helpful and was wondering if you can make a video explaining how to structure and organize big solutions, where they might have multiple parts like say SDKs they made for integrations and Helper libraries and so on that they are using in their main UI app. Also would like to know how do you do source control on them.... From what I've read some do multiple projects, some do folders within the same project some do nuget packages. Would really appreciate your take on this topic.

  • @_xentropy
    @_xentropy Před 2 měsíci

    Cool! Any idea how hard it is to implement your own transports?

  • @joeldickson5471
    @joeldickson5471 Před 2 měsíci

    It's a bit "springlike", but not as much magic as spring, so it's OK I think, I'll give it a go. But I'm not sure it'll work well with kafka where you need to carefully plan your keys for scaling. It's the same woth most service bus abstractions I find

  • @igorilyichyov6414
    @igorilyichyov6414 Před 2 měsíci

    Great video!

  • @salaheddinneelbakkerri5795
    @salaheddinneelbakkerri5795 Před 2 měsíci

    thx for all your video Nick, and i have a little confusion between Wolverine and event,please answer me.Wolverine it can replace "event" in dotnet???

  • @d3synchronisation
    @d3synchronisation Před 2 měsíci

    That's an awesome video. Thank you. I d like your 2 cents on a project that I am working, and also whether I could use Wolverine for that particular project. I have a Windows Service app in .NET Core that works as a bridge between a system and a Web Service (SOAP if that matters). The Windows Service reads a sql table if there are any new records every X time and it adds them to a BlockingCollection and updates a bit on the db that those records were loaded .
    The app needs to be quick so there are 3-4 tasks that check the BlockingCollection for new entries and consume an item in order to communicate with the Web Service and record the response into a different database table. Could I replace that part of the code with wolverine and the SqlServer nuget to have the same effect, instead of using my not so well written code ?

  • @kirillhorn3186
    @kirillhorn3186 Před 2 měsíci +1

    Automagically 😂 this is brilliant!

  • @vic10us
    @vic10us Před 2 měsíci +4

    Fantastic video as usual. I am curious though why you would need to specify a queue for publishing in RabbitMQ? The queue should be defined by the consumer no?

    • @nickchapsas
      @nickchapsas  Před 2 měsíci +4

      Yeap you are right. Originally when I planned the video I showed the consumer first so I used the wrong code sample.

  • @nick_stelmakh
    @nick_stelmakh Před 2 měsíci

    Perfect :)

  • @julienraillard3567
    @julienraillard3567 Před 2 měsíci

    Awesome content as always 😁. Would you prefer MassTransit over Wolverine or contrary and why so ? :)

  • @dovh49
    @dovh49 Před 2 měsíci

    So, can you return a result type that also contains events to be published?
    Result types make it easy to have a uniform API end points, as the API part can parse the which result type is returned and create a proper message to return on your API. But if you want to publish an event that could be cool too. I suppose you could just manually publish the event if you are doing that. But it would be nice to see an example of this pattern.
    One thing that I like to say about the Result type is that it doesn't handle errors, it handles short circuiting your code and returning a message. So, it is more of a messaging way to talk to upper level codes explicitly. Without the cost of throwing exceptions.

  • @anonymoususer6801
    @anonymoususer6801 Před 2 měsíci

    Would be cool if you can do from configuration like add bearer auth is working right now.

  • @kinax2
    @kinax2 Před 2 měsíci

    Hi Nick, thank you for the video.
    what is better? MassTransit or Wolverine

  • @yazidarezki3757
    @yazidarezki3757 Před 2 měsíci

    Great video, can one use Wolverine with MongoDB ?

  • @user-sc9if7uw9f
    @user-sc9if7uw9f Před 2 měsíci

    Hi Nick, I think it would be interesting to create video content on how to read messages from event hub and send that messages to data source Mimir and consume the data from Mimir in another web api that displays it, instead displaying it in grafana.

  • @temp50
    @temp50 Před 2 měsíci

    11:43: That won't happen in this scenario.
    Logging alone IS a side effect next to handling the original request.
    If you call the method multiple times, the timestamp of the log entry will always be different as an example

  • @atul121984
    @atul121984 Před 2 měsíci +1

    Looks excellent for use.

  • @snapching
    @snapching Před 2 měsíci

    All implementation on an async messaging pattern. My personal preference is to think through the business process, and then speak to patterns that are reliable and asynchronous. Tough to do in a short video. However, showing implementation without business context will likely mean devs will jump on this and not be prepared for the complexity of managing a distributed, multi threaded (or process) application.

  • @woksin
    @woksin Před 2 měsíci +3

    How would you feel about the conventional stuff if they also packaged a set of roslyn analyzers that would check against these conventions?

    • @Scroapy
      @Scroapy Před 2 měsíci +4

      I hate conventional stuff in almost any case. It forces ALL developers in the team to be aware of ALL conventions. That makes onboarding new people on the project harder, because it is easier when you have contracts everywhere, since you can already see/navigate into the package which does something with that piece of code aka it is self documented.

    • @woksin
      @woksin Před 2 měsíci

      ⁠​⁠​⁠@@Scroapyfair enough, many developers don’t like conventional magic, and without good tooling it can lead to situations where it’s hard to figure out what’s going on. Though in Wolverine it is btw possible to configure the discovery manually with your own conventions, or disable automatic discovery all together and rely on attributes if you so wish (worse or better than forcing interfaces on your code?)
      For learning and adapting to a new set of conventions there are two starting points. 1) green field project, or introducing a new framework, where there is some initial learning curve and probably some failures and frustrations. And 2) an existing project with already written code with these conventions, then just reading the existing code should guide you in that direction. If the developers struggle to adapt to conventions in a code base with guidance then I would worry about other problems

  • @ayattmohamed3616
    @ayattmohamed3616 Před 2 měsíci

    THANKS 👍👏👏👏🤝🤝

  • @bevilton8375
    @bevilton8375 Před 2 měsíci

    Great vid! But what about MassTransit with its messaging/request-response? It is still more usable IMO.

  • @flybyw
    @flybyw Před 2 měsíci +10

    Why did I have a feeling at first that the magic is based on reflection, and not NativeAOT-friendly?

    • @alexisfibonacci
      @alexisfibonacci Před 2 měsíci

      Is it AOT-friendly?

    • @thomaskmfdm
      @thomaskmfdm Před 2 měsíci

      Isn't that why the dev uses his own DI so that it is nativeAOT friendly?

    • @fredrikandersson4918
      @fredrikandersson4918 Před 2 měsíci +1

      It uses code generation from what I can see.

    • @awright18
      @awright18 Před 2 měsíci

      It uses source generators. There are some examples on the wolverine website of the generated code.

  • @stanislav7228
    @stanislav7228 Před 2 měsíci +4

    Hi Nick, Thanks for the video. I'm using MassTransit and would it would be awesome to have a video about it as well. And with some comparison points between Wolverine with your opinion would be even better!

  • @meirkr
    @meirkr Před 2 měsíci

    WOW. One of the most best videos!!! Like++++++++++

  • @jakosss
    @jakosss Před 2 měsíci +5

    While this really looks nice, i hate implicit frameworks like this. It's the same problem i had with reflection in WPF apps and AutoMapper IL code generation. MassTransit for me is just explicit, i can track what is happening without having to learn the conventions. And i imagine - debugging issues with implicit framework like that might end up with nightmares

  • @JonathanPeel
    @JonathanPeel Před 2 měsíci

    Sometime, please do a video on your thoughts on MassTransit.
    It might have a bit more config than something like MediatR, but also very versatile.

    • @logantcooper6
      @logantcooper6 Před 2 měsíci

      He already has

    • @JonathanPeel
      @JonathanPeel Před 2 měsíci

      ​@@logantcooper6, I'm sure, but once a channel has as many videos as what Nick does it is not always as obvious... My memory isn't that good anymore 😂

  • @AndrzejCzarkowski
    @AndrzejCzarkowski Před 2 měsíci +4

    I don't use any of those libraries. They are all very opinionated. I build simple Web API projects with Outbox pattern. I then use Change Feed to dispatch the messages (I use CosmosDb). Then on the receiving end I have a simple service that receives a message and simply makes POST http requests with the received message. Will add tiny but of latency for sure but when you use messaging you already accept the fact that you add extra latency to your applications. I can that way also test my service end to end using tools like Postman.

  • @jorgen7842
    @jorgen7842 Před 2 měsíci

    Is there a way to publish the messages without a BackgroundService class? like normal windows or console apps that don't need to run constantly

  • @user-bx2er2zx5u
    @user-bx2er2zx5u Před 2 měsíci +1

    Is there a course planned related to asynchronous communication or something similar?

  • @giszTube
    @giszTube Před 2 měsíci +1

    We use MediatR and I wonder if by the time we upgrade (we are many versions back), the API will be like that of Wolverine.

    • @jeremymiller9966
      @jeremymiller9966 Před 2 měsíci +1

      It won't. The internal approach between MediatR & Wolverine is very different.

  • @dennycrane2938
    @dennycrane2938 Před 2 měsíci

    What I really wanna see is a good framework that can also deal with dead-lettering

  • @JohanNordberg
    @JohanNordberg Před 2 měsíci

    What are the main pros and cons with this over classics like MassTransit and RabbitMQ?

  • @bartvankeersop8218
    @bartvankeersop8218 Před 2 měsíci +9

    Interested how this compares to MassTransit. What are the reasons to pick one over the other?

    • @TehGM
      @TehGM Před 2 měsíci +2

      This is important, especially if this one replaces the DI container silently. That's a big ask, so there needs to be enough reason, or MassTransit is simply an easy choice.

    • @allinvanguard
      @allinvanguard Před 2 měsíci +4

      From what I read and heard so far, Wolverine looks very nice, but it also looks like it mainly just has feature parity, and in this case I do not know why I would want to use it over MassTransit, which is a tried and tested framework

    • @jessestruyvelt7593
      @jessestruyvelt7593 Před 2 měsíci +1

      It's totally different to MassTransit, which is a framework that forces ideas upon you, unlike Wolverine. Much more flexible and easy to use.

  • @winstonstrongarm8929
    @winstonstrongarm8929 Před 2 měsíci

    Been waiting for this ever since I saw you joined the Critter Stack Discord.
    This is a great overview, Ive sent the link to all my co-workers in hopes they'll start using Wolverine more😅

    • @nickchapsas
      @nickchapsas  Před 2 měsíci +3

      I'm not in the Critter Stack Discord 🤔

    • @ferd1775
      @ferd1775 Před 2 měsíci

      @@nickchapsas lol

  • @T___Brown
    @T___Brown Před 2 měsíci

    I was hoping you would show how it handles topics.

  • @GarethDoherty1985
    @GarethDoherty1985 Před 2 měsíci

    Can this be used to monitor an Azure service bus queue where messages are written to it from other things which aren't using Wolverine?

  • @Reverence12389
    @Reverence12389 Před 2 měsíci

    Would like to see an NServiceBus Video

  • @kayhantolga
    @kayhantolga Před 2 měsíci +5

    string matching for method names!? in 2024!? what are we, javascript developers??

  • @nicklasblomqvist1122
    @nicklasblomqvist1122 Před 2 měsíci

    A ServiceBus video would be great! It's not a great experience registering a bunch of consumers with background services e.t.c. Would be great to get your view on it all and make our daily life a bit better.

  • @bruno.arruda
    @bruno.arruda Před 2 měsíci +21

    "Deadpool & Wolverine (2024) Trailer Now Out!"

    • @maacpiash
      @maacpiash Před 2 měsíci +6

      Threadpool and Wolverine (2024)

  • @stevenbey
    @stevenbey Před 2 měsíci

    What did you mean by "use the @ symbol to deconstruct the object"?

    • @tafs7
      @tafs7 Před 2 měsíci

      In structured logging, as with a logging lib like Serilog, you can "destructure" all public object properties into your log message as part of the log payload, so you don't have to manually define a message template string that provides each separate public property. Warning: This can be dangerous as you could overexpose data from your objects into your log, and accidentally log secrets or PII data, etc.

  • @arjunav7259
    @arjunav7259 Před 2 měsíci

    Dear Nick,
    Can you please create a tutorial on how to do integration testing for Generic host non-Web application eg - Background service which acts as a RabbitMQ Subscriber.

  • @event-sourcing
    @event-sourcing Před 2 měsíci

    Love that you're highlighting Wolverine! It, and the entire Critter Stack of libraries from JasperFX are excellent.

  • @florentbunjaku4278
    @florentbunjaku4278 Před 2 měsíci

    Reasoning the duct type with "having one class handling multiple messages" is not very convenient as you can achieve the same with multiple interfaces.

  • @alexbeloff4618
    @alexbeloff4618 Před 2 měsíci

    Forcing its own DI container stopped me right there... Sorry, I can't do it in my projects.

  • @mortenmoulder
    @mortenmoulder Před 2 měsíci +2

    I am not a fan of how the handlers simply "do stuff". It's weird. Was it based on naming or the arguments of the "Handle" method? Hmm.

  • @EraYaN
    @EraYaN Před 2 měsíci +2

    So it’s like a more opinionated Rebus or even MassTransit which is a much larger framework.

    • @jessestruyvelt7593
      @jessestruyvelt7593 Před 2 měsíci

      It's a library, MassTransit is a framework and works very very differently. MassTransit forces you to use it in a certain way, Wolverine is much more flexible.

    • @EraYaN
      @EraYaN Před 2 měsíci +2

      @@jessestruyvelt7593 Hence why I mentioned Rebus first.

    • @jessestruyvelt7593
      @jessestruyvelt7593 Před 2 měsíci

      @@EraYaN I see. We are using Wolverine in production, couldn’t be happier

  • @satyayuga0
    @satyayuga0 Před 2 měsíci +1

    Deadpool & Wolverine (2024) Trailer Now Out!

  • @helshabini
    @helshabini Před 2 měsíci +1

    I don't think this has any functional benefits over tried and true MassTransit. Both have Sending/Publishing/Responding. MassTransit can do a lot more with Sagas.
    I don't like the DI Container replacement. I would never do that. I also don't like that the initialization syntax is transport-dependent. Which means I will have to re-write all my initialization syntax if I ever want to change transports (which may happen especially in early stages of a project). In MassTransit, initialization is done outside the boundaries of transport definition, which allows me to switch transports without any changes to my code.

  • @rapzid3536
    @rapzid3536 Před 2 měsíci

    This is a long video. Does it support domain events that need to participate in the same transaction? Does it support Postgres as an event queue? Can it be used with Autofac?!

  • @JackFord322
    @JackFord322 Před 2 měsíci +2

    Is Wolverine a MassTransit killer, like Bun is Node killer?

    • @xRealHackerx
      @xRealHackerx Před 2 měsíci +9

      Wolverine is a joke compared to MassTransit.

    • @JackFord322
      @JackFord322 Před 2 měsíci

      @@xRealHackerx so i said

    • @deathrace-bx5ne
      @deathrace-bx5ne Před 2 měsíci

      Wolverine will definitely be slower than MassTransit due to reflection based code handlers.

    • @woksin
      @woksin Před 2 měsíci +5

      @@deathrace-bx5ne Have you even investigated this? Wolverine relies heavily on code generation and actually wraps itself around your code instead of relying on reflection

    • @mysteriouslyhandmade
      @mysteriouslyhandmade Před 2 měsíci +7

      The simple fact that a messaging library will replace your DI library is ridiculous. Masstransit already wins there.

  • @talwald1680
    @talwald1680 Před 2 měsíci +1

    I think that this could have been a simpler api, if you went for something like what minimal api did, but instead of MapGet() you could have SubscribeTo() and pass the DI services and the message itself.
    No need for separate classes unless you decide to create them.
    What do you think?

  • @peterhuijsen
    @peterhuijsen Před 2 měsíci +2

    I really don't like the way in which Wolverine relies upon conventions instead of contracts. To me it feels wrong, unsafe, to write code as opinionated as this. Contracts make it clear and simple what is expected and thus what should be implemented. Now, however, with Wolverine you can't rely on these tools. I know this is personal but I would dread writing code like this. It's too much "magic" which obfuscates the way in which it works which results in it being harder to read and parse. Saving the "bloat" of interfaces doesn't seem worth it to me.

  • @deathrace-bx5ne
    @deathrace-bx5ne Před 2 měsíci

    So, from handler side it must be using Reflection that means performance hit. Hmmmm...

  • @KeesAlderliesten
    @KeesAlderliesten Před 2 měsíci

    2:16 after weeks of 'we just launced..' maybe replace 'we just' with 'some time ago we'.. 🙂

  • @theguy920
    @theguy920 Před 2 měsíci

    this shit at 0:12 just cost me $12.49

  • @xRealHackerx
    @xRealHackerx Před 2 měsíci +5

    Wolverine docs:
    Build clean messaging with:
    - Todo
    - Todo Todo
    - Todo Todo todo

    • @jeremymiller9966
      @jeremymiller9966 Před 2 měsíci +10

      Dude, there's a handful of "TODO" scattered in there in between about 75 pages full of documentation with examples everywhere. Maybe chill out a little bit on the quick criticism.

  • @Drauchris
    @Drauchris Před 2 měsíci +2

    I hate opinionated code if it does not match my opinion

  • @MrLeri09
    @MrLeri09 Před 2 měsíci

    Too much magic going on behind the scenes. This will lead to debugging hell in the real-world projects.