If you're interested in more content around using MediatR and Hangfire together let me know. There's a few different things such as event handlers, retries, timeouts and how you can deal with them. Let me know in the comments what your interested in.
After watching this video, I've been looking around for a way to ensure messages enqueued to Hangfire's SQL Server storage are committed in the same db transaction as my Entity Framework Core DbContext class. Do you have any insights on this?
@@codyspeck Good question! I haven't looked at this but I can see how you'd want this for something like the outbox pattern when using Hangfire. I might look into this further, stay tuned!
After some more trying out, I really like this approach since we are able to use both the MediatR Send or the extension method you wrote where needed to switch between in and out process.
@@CodeOpinion Thank you. I'm facing some weird issue like, I'm throwing "NotImplementedException" but my hangfire wasn't retry. Status of my job is "Succeeded"
Is the use of MediatR relevant to hooking a CQRS implementation up to HangFire? Or is it a matter of extending whatever CQRS implementation you have to another method that moves that work out of process?"
I did't understand how you managed to use mediator to talk with a separate process(the worker which hosts hangfire).As fire as i know medior works only in process.I think would me more suitable a message broker for interprocesses comunications
I'm not the author of Brighter. Ian Cooper (twitter.com/ICooper) and other contributors are who created Brighter. I just enjoy looking at different message/command processors and how they work. I wanted to illustrate how you could use Hangfire as message dispatcher and MediatR as the processor, mainly because Hangfire has a bunch of nice features out of the box like retries and failed queue.
I have been using dependency injection using Dapper, I have tried several ways to get to my Handler using MediatR but when I run Hangfire and get to the controller I find that I must correct the problem with dependency injection. I have also tried configuring my controller by creating an additional service to go through there, but I always run into the same problem. any recommendation or help
the hangfire can job with topic equals rabbit mq? in this example, when have a implementation witch listen a new Order event receive? i said this because, i need to execute anothers methods after create event new Order. can explain?
Thanks for video! Very helpful! One question. Where should be located "Handle" method for processing data and do something? I suppose that it should be inside "Handfire.Mediatr" project, am I right? So "Handfire.Mediatr" project included in "Worker" and in "AspNetCore". "AspNetCore" use it to serialize information about data and method to be called and send ti Handfire storage. And "Worker" use "Handfire.Mediatr" to deserialized record from Handfire storage and execute needed method?
Yes, Hangfire.MediatR is referenced in AspNetCore and Worker projects. The the relevant message and handlers would be in their own respective projects like Sales, Shipping, etc.
Hii , Is it good approach to use Hangfire with the EntityFrameworkCore.Triggered library to easily replicate data from the write database to the read database whenever there are changes. What are your thoughts on this approach? Do you think it's a good idea or are there any potential issues we should be aware of?
@@CodeOpinion This library allows you to easily add triggers to your database operations, similar to how triggers work in a traditional SQL database. These triggers can perform additional actions, such as updating related records, when certain conditions are met, making it easier to maintain data integrity and enforce business rules.
I was wondering as well. I read through the comments and Derek seemed to have tried out the MediatR Publish as well. Since he used the Send method instead of Publish it will never reach that code. Was considering this approach as well but can't seem to figure out if the Hangfire+MediatR publish could be a substitute to NServiceBus/CAP or similar packages. Hopefully Derek can shed some light on this!
You would need to know the mapping between the Event and the Consumer Handlers so you could create a hangfire job for each handler type. Then for each job, have it resolve/create that specific handler and invoke it.
Did you abandon this concept after digging in realizing it wasn't a good approach? Just haven't seen anything along these lines since Sep 3 2020 and am trying to determine if this is still a valid approach. Also, if it is - does the worker have to depend on Hangfire.AspNetCore && Hangfire.SqlServer (this seems to be the only way for me to get it to allow the service add) && there doesn't seem to be any libraries of hangfire that I can see that combines the two into a dependency injection situation.
No it's still valid for many simple use-cases. Yes you would depend Hangfire.AspNetCore which has the IServiceCollection.AddHangfire() and IApplicationBuilder.UseHangfireServer(). You also need a package for storage, this could be Hangfire.SqlServer or others.
Hi, nice. But! Why do we code all these bridge and extensions staff but not call the mediator Send as below? In the end we can switch out of process like this. What is the benefit or difference? BackgroundJob.Enqueue(m => m.Send()); public interface IMyJob { [DisplayName("My Job")] Task Send(); } public class MyJob : IMyJob { private readonly ISender _mediator; public MyJob(ISender mediator) { _mediator = mediator; } public async Task Send() { await _mediator.Send(new MyRequest()); } }
At first, Postman showed "842ms". So, is that a lot of latency (say, by-product of process level indirection, or rather MVC?)?. It will be helpful if you could give some insights on improving on that front should be equally in part due to the use of MediatR, etc. Of course, this will only increase from what it looks (though, benefits outweigh given the "pre implement" latency)?. Overall, feels like a bit too much for achieving something which should be available in the language with relative simplicity?.
That's because it was the first call. It's .NET so it uses JIT compilation (IL into machine code, when you execute a path in the program). Subsequent requests would probably be 2 orders of magnitude faster.
Publish is for publishing an event/notification. Which may have zero or many handlers. All of them are done in-process when you call Publish. Meaning if one event handler throws an exception it will bubble up to where you call Publish. Using Hangfire jobs to process the handlers make them independent and execute in isolation out of process.
@@CodeOpinion Great content -- thank you! How would you extend what you have learned here to Publish an event using MediatR but ensure that the zero to many published event handlers are enqueued and processed out-of-process with Hangfire?
@@coderanger75 Yes you could do the same thing for event handlers. You would need to means to know which event handlers exist for an event at publish time (using reflection or some mapping), then enqueue a job for each event handler. You would then need to extend MediatR to execute an event handler for an event individually that was the job in Hangfire.
Hangfire is awesome. Adding MediatR to the mix is just a way to add a command pattern to the mix instead of Hangfires built in way of performing background jobs. Brighter by design does this plus a bunch of things you will have to implement manually with a Hangfire + MediatR setup (such as custom retry logic, outbox pattern, etc).
@@CodeOpinion Thanks for quick reply. Looks like it takes a lot of boiler plate code to implement hangfire + mediatr compared to brighter. Other than that, any suggestions on which one to choose for production scenario? The setup pretty much is similar to python+celery+rabbitmq/others.
@@CodeOpinion please also cover saga and distributed transaction.. also in above example... Doest it mean we can use hangfire instead of Rabbitmq to publish our integration events...
@@CodeOpinion got the answer for second part i.e Rabbitmq in your comments.. thanks... Also waiting for saga and distributed transaction... Thanks in advance
@@CodeOpinion Thanks - Just looking over the code I think I just got the idea of bounded contexts! I do have a question about this video and if you have had this in your experience of using Mediatr, Hangfire and DbContext...specifically with the dreaded "Second operation started on this context before a previous completed?" This happened in my setup and I think I gave up.
@@SwampyFox So this is because the DbContext is probably Scoped at the root level DI service provider so you have the same DbContext being used between different handlers that are running concurrently. I'll try and replicate and fix it in my code sample.
If you're interested in more content around using MediatR and Hangfire together let me know. There's a few different things such as event handlers, retries, timeouts and how you can deal with them. Let me know in the comments what your interested in.
This looks like a better solution that the previous Brighter demo. I'd be keen for more videos on extending this.
After watching this video, I've been looking around for a way to ensure messages enqueued to Hangfire's SQL Server storage are committed in the same db transaction as my Entity Framework Core DbContext class. Do you have any insights on this?
@@codyspeck Good question! I haven't looked at this but I can see how you'd want this for something like the outbox pattern when using Hangfire. I might look into this further, stay tuned!
@@CodeOpinion Exactly the pattern I'm trying to implement. Cheers!
@@CodeOpinion Any updates on this?
I'm binge watching your videos. Love the format, short and very informative. Thanks !
Thanks for watching!
Why is this channel is so underrated. 😔
Share! It's growing as time goes on and publish more content.
Why do u have only 4k subs ?! Your videos are so good.. Keep it up
Good question! Share with your friends and co-workers! :)
After some more trying out, I really like this approach since we are able to use both the MediatR Send or the extension method you wrote where needed to switch between in and out process.
Yup, its advantage is it the same model for in and out of process. For a lot of use cases this works pretty well.
Would love more videos on this. Would you extend MediatR publish method too?
I have. It's a bit more involved but possible.
Great video.
Question - would you not get the same effect if you invoke hangfire in the MediatR handler?
You want hangfire to execute/invoke the handler or whatever code you want to run separately.
Awesome, Great article.
I have a doubt, is there any way to run the worker project inside my API.
I don't want to run two applications.
Yes, you can run Hangfire right along side ASP.NET Core
docs.hangfire.io/en/latest/getting-started/aspnet-core-applications.html
@@CodeOpinion Thank you.
I'm facing some weird issue like, I'm throwing "NotImplementedException" but my hangfire wasn't retry.
Status of my job is "Succeeded"
Is the use of MediatR relevant to hooking a CQRS implementation up to HangFire? Or is it a matter of extending whatever CQRS implementation you have to another method that moves that work out of process?"
Good job Derek!!!
Thanks!
I did't understand how you managed to use mediator to talk with a separate process(the worker which hosts hangfire).As fire as i know medior works only in process.I think would me more suitable a message broker for interprocesses comunications
Hello,
Is it possible to share data between Hangfire jobs using this pattern ?
Or do you know a solution to make it possible with an other way ?
What do you think on this version vs Brighter. I know you are the author of Brighter so I'm curious on your thoughts.
I'm not the author of Brighter. Ian Cooper (twitter.com/ICooper) and other contributors are who created Brighter. I just enjoy looking at different message/command processors and how they work. I wanted to illustrate how you could use Hangfire as message dispatcher and MediatR as the processor, mainly because Hangfire has a bunch of nice features out of the box like retries and failed queue.
@@CodeOpinion ah sorry. I saw your name on the Paramore Brighter CommandStore page and thought you were one of them.
how to combine recurring job and mediator pattern?
I have been using dependency injection using Dapper, I have tried several ways to get to my Handler using MediatR but when I run Hangfire and get to the controller I find that I must correct the problem with dependency injection. I have also tried configuring my controller by creating an additional service to go through there, but I always run into the same problem. any recommendation or help
the hangfire can job with topic equals rabbit mq? in this example, when have a implementation witch listen a new Order event receive? i said this because, i need to execute anothers methods after create event new Order. can explain?
Thanks for video! Very helpful!
One question. Where should be located "Handle" method for processing data and do something? I suppose that it should be inside "Handfire.Mediatr" project, am I right? So "Handfire.Mediatr" project included in "Worker" and in "AspNetCore". "AspNetCore" use it to serialize information about data and method to be called and send ti Handfire storage. And "Worker" use "Handfire.Mediatr" to deserialized record from Handfire storage and execute needed method?
Yes, Hangfire.MediatR is referenced in AspNetCore and Worker projects. The the relevant message and handlers would be in their own respective projects like Sales, Shipping, etc.
Hii , Is it good approach to use Hangfire with the EntityFrameworkCore.Triggered library to easily replicate data from the write database to the read database whenever there are changes.
What are your thoughts on this approach? Do you think it's a good idea or are there any potential issues we should be aware of?
Never heard of that library, I'll have to check it out.
@@CodeOpinion This library allows you to easily add triggers to your database operations, similar to how triggers work in a traditional SQL database. These triggers can perform additional actions, such as updating related records, when certain conditions are met, making it easier to maintain data integrity and enforce business rules.
Hi, How do you get back to the CreateShippingLabel with this code? I never reach the Inotification point entry? thanks
I was wondering as well. I read through the comments and Derek seemed to have tried out the MediatR Publish as well. Since he used the Send method instead of Publish it will never reach that code. Was considering this approach as well but can't seem to figure out if the Hangfire+MediatR publish could be a substitute to NServiceBus/CAP or similar packages. Hopefully Derek can shed some light on this!
After some searching.. some comments below by "Gabriel B" shows the exact answer of what we wanted to know :)
You would need to know the mapping between the Event and the Consumer Handlers so you could create a hangfire job for each handler type. Then for each job, have it resolve/create that specific handler and invoke it.
Did you abandon this concept after digging in realizing it wasn't a good approach? Just haven't seen anything along these lines since Sep 3 2020 and am trying to determine if this is still a valid approach. Also, if it is - does the worker have to depend on Hangfire.AspNetCore && Hangfire.SqlServer (this seems to be the only way for me to get it to allow the service add) && there doesn't seem to be any libraries of hangfire that I can see that combines the two into a dependency injection situation.
No it's still valid for many simple use-cases. Yes you would depend Hangfire.AspNetCore which has the IServiceCollection.AddHangfire() and IApplicationBuilder.UseHangfireServer(). You also need a package for storage, this could be Hangfire.SqlServer or others.
Thanks. Another great content.
Hi, nice. But!
Why do we code all these bridge and extensions staff but not call the mediator Send as below? In the end we can switch out of process like this. What is the benefit or difference?
BackgroundJob.Enqueue(m => m.Send());
public interface IMyJob
{
[DisplayName("My Job")]
Task Send();
}
public class MyJob : IMyJob
{
private readonly ISender _mediator;
public MyJob(ISender mediator)
{
_mediator = mediator;
}
public async Task Send()
{
await _mediator.Send(new MyRequest());
}
}
At first, Postman showed "842ms". So, is that a lot of latency (say, by-product of process level indirection, or rather MVC?)?. It will be helpful if you could give some insights on improving on that front should be equally in part due to the use of MediatR, etc.
Of course, this will only increase from what it looks (though, benefits outweigh given the "pre implement" latency)?.
Overall, feels like a bit too much for achieving something which should be available in the language with relative simplicity?.
That's because it was the first call. It's .NET so it uses JIT compilation (IL into machine code, when you execute a path in the program). Subsequent requests would probably be 2 orders of magnitude faster.
Very interesting!
Awesome!
Can i run hangfire completely different machine or container in kubernetes? Will it work 🤔
Yes
@@CodeOpinion yes tested that but its not an efficient way to use hang fire. Better option is rabbitmq
Dumb question, what's the difference from this method versus mediatr.Publish, other than the persistance and the retry mechanism?
Publish is for publishing an event/notification. Which may have zero or many handlers. All of them are done in-process when you call Publish. Meaning if one event handler throws an exception it will bubble up to where you call Publish. Using Hangfire jobs to process the handlers make them independent and execute in isolation out of process.
@@CodeOpinion thanks, I really liked this approach, is way way better than having to publish another event!
@@CodeOpinion Great content -- thank you! How would you extend what you have learned here to Publish an event using MediatR but ensure that the zero to many published event handlers are enqueued and processed out-of-process with Hangfire?
@@coderanger75 Yes you could do the same thing for event handlers. You would need to means to know which event handlers exist for an event at publish time (using reflection or some mapping), then enqueue a job for each event handler. You would then need to extend MediatR to execute an event handler for an event individually that was the job in Hangfire.
@@CodeOpinion I greatly appreciate the advice! Can't wait to try this out today.
Hangfire + MediatR vs Brighter -->what's your opinion?
Hangfire is awesome. Adding MediatR to the mix is just a way to add a command pattern to the mix instead of Hangfires built in way of performing background jobs. Brighter by design does this plus a bunch of things you will have to implement manually with a Hangfire + MediatR setup (such as custom retry logic, outbox pattern, etc).
@@CodeOpinion Thanks for quick reply. Looks like it takes a lot of boiler plate code to implement hangfire + mediatr compared to brighter. Other than that, any suggestions on which one to choose for production scenario? The setup pretty much is similar to python+celery+rabbitmq/others.
Where can I find the source code?
github.com/dcomartin/LooselyCoupledMonolith/tree/HangfireMediatR
@@CodeOpinion please also cover saga and distributed transaction.. also in above example... Doest it mean we can use hangfire instead of Rabbitmq to publish our integration events...
@@CodeOpinion got the answer for second part i.e Rabbitmq in your comments.. thanks...
Also waiting for saga and distributed transaction... Thanks in advance
Is the code available?
Sorry, should of included it in the description.
github.com/dcomartin/LooselyCoupledMonolith/tree/HangfireMediatR
@@CodeOpinion Thanks - Just looking over the code I think I just got the idea of bounded contexts! I do have a question about this video and if you have had this in your experience of using Mediatr, Hangfire and DbContext...specifically with the dreaded "Second operation started on this context before a previous completed?" This happened in my setup and I think I gave up.
@@SwampyFox So this is because the DbContext is probably Scoped at the root level DI service provider so you have the same DbContext being used between different handlers that are running concurrently. I'll try and replicate and fix it in my code sample.