1

We have a .net core app with the following folder / onion structure:

WidgetApp -> Core -> Application -> JobAutoStarter -> JobAutoStarter.cs
WidgetApp -> Core -> Domain -> Entities
WidgetApp -> Infrastructure -> Hangfire -> WidgetJobs ->  Job1  (hangfire job logic)
WidgetApp -> Infrastructure -> Hangfire -> WidgetJobs ->  Job2
WidgetApp -> Infrastructure -> Persistence -> WidgetDb
WidgetApp -> Presentation -> (various Apis)

The JobAutoStarter is a new feature we are going to add to our app. When the app starts, the first thing it will do is check the db for a list of Hangfire jobs that need to be auto started (based on other domain specific criterion and not just what's configured in hangfire This is why the class right now is in the application layer) If it finds a job that should be started, then the JobAutoStarter class currently includes methods like:

            try
            {
                AssignHangfireJobNumber(jobDetails);
                UpdateHangfireJobInstance(jobDetails);
                ScheduleJobInHangfire(jobDetails);
                UpdateAssignedHangfireJobNumber(jobDetails);
                
            }
            catch (Exception ex)
            {
            }

I don't really want the application layer to know so much about the inner workings of Hangfire. But, in an onion, I don't think it's good design for the application layer to "know" about stuff in Infrastructure either, if I understand correctly. I was thinking of creating for example:

WidgetApp -> Infrastructure -> Hangfire -> Common -> JobAssigner.cs WidgetApp -> Infrastructure -> Hangfire -> Common -> JobInstanceUpdater.cs
WidgetApp -> Infrastructure -> Hangfire -> Common -> JobScheduler.cs

But not sure if that would break my onion or not. So Just looking for some suggestions on how to organize this code.

1 Answer 1

5

When the app starts, the first thing it will do is check the db for a list of Hangfire jobs that need to be auto started (based on other domain specific criterion and not just what's configured in hangfire This is why the class right now is in the application layer)

This "domain specific criterion" really needs to fleshed out. It sounds like there will be some custom behavior code that makes some decisions about starting jobs. That will need to live somewhere where the info it needs is available.

Fortunately, in an onion, info can go all over the place:

enter image description here

That works, even when enforcing inward pointing static code dependencies between layers, by simply following DiP.

But it's still best to make decisions close to the needed info. The key isn't to wall off communication. It's to simplify what needs to be communicated through your walls.

I don't really want the application layer to know so much about the inner workings of Hangfire.

Simple abstraction takes care of that. Inner working knowledge isn't needed to use something that is decently abstracted. If an appropriate abstraction for your needs doesn't exist, build one.

But, in an onion, I don't think it's good design for the application layer to "know" about stuff in Infrastructure either

Turns out that depends on whose onion diagram you're looking at:

anarsolutions.com - What makes Onion Architecture so popular among techies?

Here it looks like it's ok for Application to know about Infrastructure Services.

dzone.com - Onion Architecture Is Interesting

But here it looks like Application shouldn't know about Infrastructure at all.

The truth is there is no one true onion. But your code should at least consistently follow one design.

Also, be aware that folder structure and onion layers do not have a 1 to 1 relationship. Be careful about attempting to force them to have one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.