Hangfire implementation in Repository pattern
Hi, sorry for newbie question.
I am trying to add hangfire to my project. I believe I am using DDD to the best of my ability
trying to incorporate hangfire and follow DDD architecture i've hit a snag.
here is some code snippet from my hangfire implementation in each layer:
https://paste.mod.gg/ynibbxjvpvfc/0
and below is my project structure:
├───App.Presentation
│ ├───Controllers
│ └───Properties
├───App.Application
│ └───Services
├───App.Domain
│ └───Aggregates (or I believe more commonly people call them entities)
├───App.Infrastructure
│ └───Persistence
│ └───Repositories
└──
I've only installed hangfire related packages in infrustructure layer (Hangfire.AspNetCore & Hangfire.PostgreSql)
due to doing so I only have access to the hangfire methods in infrustructure. now when I wanna use/implement in application layer
RecurringJob.AddOrUpdate(string, Expression<Action>,CRONEXPRESSION)
I pass my JobService a string and I cannot utilize the hangfire method Corn.daily() or other methods provided by hangfire itself.
I really could use your help to know whether I should install hangfire.AspNetCore in application ? and remove it from infrastructure and leave the Hangfire.PostgreSql in infrustructure or what.
really appreciate your kind assistance on this. please let me know if I should provide you with more details.
I would also be very thankful if you could direct me to a code example of hangfire implementation in DDD and Repository pattern.
cheers
BlazeBin - ynibbxjvpvfc
A tool for sharing your source code with the world!
5 Replies
if my understanding of Clean Architecture that you seemingly try to implement and DDD is correct then your
App.Domain
should not hold such IJobRepository
interface but only Domain Models.
then your Infrastructure
uses domain model object as input for Create, Update and Delete operations instead of values, and it returns domain model/-s on Get methods. This is how you pass values through your layers, they are contained in your model that Infrastructure returns to Application on a Get, or respectively that Application passes to Infrastructure on a Create, Update, Delete. So thats where you get the string from and how you set it.
If you need the hanfire.AspNetCore thing in Application to create the model and pass it a string that you need, so that you can call Create() of your Repostirory then yes I think that's where it belongs.
And doing a quick glance on what hangfire is, a way to perform background processes, that should generally be part of the Application Layer, the Infrastructure Layer would persist those jobs in your Postgres DB and nothing more
Aggregates (or I believe more commonly people call them entities)just for clarification, Aggregates does not mean the same thing as entities. Aggregates consist of entities but not every entity is an aggregate or even is part of an aggregate. Say you have an Order entity that consists of items and is made by a customer: Order, OrderItem and Customer are all entities but they're not aggregates. There is only one Aggregate here which is Order and OrderItem. An aggregate defines boundaries for a set of entities in what way you should interact with said entities. Here it means that OrderItem should only be accessed using over the Order entity because thats the Root of the Aggregate. Customer is not part of that aggregate
@Thalnos i truly appreciate your concise and yet thorough reply. And thank you for clarification on aggregate. I had the wrong idea of it 🙏 🙏
and on a side note, when you gotta include the words
And
or Or
in a method name, then you are violating SRP. You should seperate those to responsiblities into two seperate methods
two*Are you referring to AddOrUpdate method? To be honest i simply followed tht convention because the method provided by hangfire to add recurring job is recurringjob.AddOrUpdate(). Granted I'm hardly familiar with hangfire and have been only playing with it for couple of days. I'll dig around and see if they have a separate method for each of the tasks and update them to ve SRP compliant. Regardless, thanks a bunch!
yes that's what I was referring to 🙂