-1

I'm currently implementing clean architecture in my project.

My application includes various types of communication protocols (TCP, HTTPS, etc.) implemented in the infrastructure layer.

These communication protocols are responsible for handling incoming and outgoing network communications.

I need to process the incoming data and prepare outgoing data, which involves significant domain logic.

Problem:

I am unsure whether to inject domain services directly into the infrastructure layer for processing this data or to use a different approach that adheres to Clean Architecture and DDD principles.

Specifically, my questions are:

  • Is it architecturally sound to inject domain services directly into the infrastructure layer for processing data?
  • If direct injection is not advisable, what is the best practice for allowing the infrastructure layer (communication protocols) to interact with domain logic without violating the principles of Clean Architecture and DDD?
  • Would using domain events or interface-based communication be a better approach in this scenario? How would this be structured effectively?

Additional Details:

My domain services contain the core logic for data processing.

The communication protocols in the infrastructure layer are the primary components that interact with the external world.

I would appreciate guidance on the best architectural approach for this scenario, along with any examples or patterns that might be relevant.

  • 1
    I think I will cast a 3rd close vote ("needs details or clarity", there are currently 2 other pending close votes "needs more focus"). Honestly, this question describes how you try to solve a problem - but your forgot completely to describe which problem. I will vote to reopen as soon as this question gives us a specific, detailed example of what you are trying to accomplish. Please ping me when the question was improved. – Doc Brown Jan 04 '24 at 21:05
  • @DocBrown I can see your concern. I was making a guess about the parsing issue. Would help if the question confirmed my guess. Or otherwise clarified what the infrastructure v business logic concern is. – candied_orange Jan 04 '24 at 22:33
  • @candied_orange: This question here is a 100% example of an XY problem: the asker told us only about Y, but absolutely nothing about X, the problem they want to solve. I think if we want to get more specific questions, we need to tell askers clearly when they missed that mark. When we instead answer their questions by guessing around, we are implicitly telling them their question was fine and motivate others to ask in a similar vague and unspecific manner. – Doc Brown Jan 04 '24 at 22:55
  • @docbrown yeah but if you take that far enough you close everything. The weak reception proves it out. If we see no edit in response I don’t mind voting to delete. – candied_orange Jan 04 '24 at 23:47
  • @DocBrown My question is straight forward I am giving example of how to handle the case when there is a dependency between the infrastructure and domain layer that will cause a violation to the arch. If I asked the question abstractly people will not understand the question. It's architectural question so the best thing is to give example so people grasp the intention of the question. Kindly, be helpful to people, enough theorizing – Shady Shahin Jan 04 '24 at 23:58
  • @ShadyShahin please edit as requested or I’ll be joining Doc in voting to delete. Did I guess right or not? Please answer with an edit. – candied_orange Jan 05 '24 at 00:02
  • "so the best thing is to give example" - yes, but this question does not contain any example. Architecture is not an end in itself, it is a means to an end. Give us context, describe your application's goal and surroundings. tell us why you consider to "inject domain services" into infrastructure layer, that will allow to make an assessment which kind of architechture may fit to your case. From the current question text, it is not even clean if "Clean Architecture" and "DDD" is a good choice for this case. – Doc Brown Jan 05 '24 at 00:04
  • ... and don't get me wrong, this is not that we don't want to help you, but any unfocussed question which is kept as it is gives a bad example for other askers to post more of such unspecific questions, and will let the quality of the site's content degrade. This debate goes for several years here, see, for example How do I ask a "Best Practices" question? – Doc Brown Jan 05 '24 at 00:09
  • ... or see Why questions about "the correct way" are too broad - in the current form, this question here is exactly of the type which was described in that old meta post. – Doc Brown Jan 05 '24 at 07:14

2 Answers2

3

I am unsure whether to inject domain services directly into the infrastructure layer for processing this data

Why would you…

enter image description here

Ooh. I see. You’re trying to parse out business stuff to build your request model. Don’t do that.

It’s ok for the request model to hold unparsed stuff. That stuff can be parsed later by the business aware Interactors as they build entities. enter image description here

Now that’s just one way to do it. But in no case should you be letting business logic leak into the outer layers. Forget clean architecture. The OSI stack shows us how to separate transportation concerns from application concerns. Don’t shove your business rules down into TCP aware code. Resolve the TCP issues and dump the rest of the data on the next layer to deal with it.

For

osi - allroundcomputersolutions.weebly.com

The important thing to understand here is, despite the fact that you can understand every part at every layer, the layers can’t. All they care about is that green part. The rest is a payload for some other layer to deal with.

Adopt that mentality and you can separate your business aware code from your protocol aware code.

Now, with that in mind, the arrows in these diagrams show what knows about what. To know about something you either build it or get handed a reference to it.

Sure, that last one is an injection. But just because you know about something doesn’t mean it returns anything to you when you call it. Some things you call and just trust that it’ll deal with what you told it to do.

This can lead to the flow of control going off on a life of its own.

enter image description here

Which means you don't have to worry so much about flow of control when constructing the clean architecture onion. This is thanks to DiP

enter image description here

What you should worry about is that things must exist before you can shove them into other things:

enter image description here My DI pattern for constructing immutable persistent objects in CA

If that’s what you mean by “inject domain services directly into the infrastructure layer” then sure. To call something you need a reference to it. But that isn’t moving the business logic. That’s asking the business logic to do its thing.

Uncle Bob doesn’t talk that much about construction or DI in his books. His diagram is about what he wants once construction is done. If you want to read more about Dependency Injection I recommend Mark Seemann

candied_orange
  • 108,538
  • +1 needs more diagrams though – Ewan Jan 04 '24 at 20:45
  • Thanks for your detailed response. My solution for that is to use a domain services using DI in the infrastructure layer so that it will use it to pass the data to the domain service to process the incoming data from the various comm protocols. The infrastructure layer is not processing any logic it just pass what it gets to the domain service to process it. So basically, It will treat the domain services Hi take incoming data.... Hey Give me outgoing data and that's it. That will happen in any type of comm protocol implemented in the infra layer. Is that considered a violation to the arch?. – Shady Shahin Jan 04 '24 at 23:52
0

I think more detail to your question would be useful. But let me try a naive approach to answering your direct questions assuming you have some standard business process application.

  • Is it architecturally sound to inject domain services directly into the infrastructure layer for processing data?

No. If anything it should be the other way around, or (see my other answer to this similar question : Should domain services in a domain-driven design invoke the data warehouse interface?) not at all.

the core logic of your domain shouldn't care about what happens before and after processing the data. You should try and make it work purely in memory on your domain objects.

  • If direct injection is not advisable, what is the best practice for allowing the infrastructure layer (communication protocols) to interact with domain logic without violating the principles of Clean Architecture and DDD?

The infrastructure layer should not contain or call your domain logic.

The infrastructure layer should contain stuff that deals with sending your data over the wire, saving it to disks, calling external services etc

  • Would using domain events or interface-based communication be a better approach in this scenario? How would this be structured effectively?

For you scenario of "get incoming data, process it, send it out again" you should structure you application as follows

public main()
{
   while(1==1)
   {
     var dataIn = Infrastructure.IncomingClient.Get();
     var processedData = Domain.Dataprocessor.Process(dataIn);
     Infrastructure.OutgoingClient.Send(processedData)
   }
}

There is no obvious need to inject anything into anything else.

Now If you want to wrap this application up in some object, call it a "Use Case" and run it from an even simpler application, then sure have it reference interfaces for the various objects and inject them. Then your references all flow in the right direction.

Ewan
  • 75,506
  • I didn't understand your last solution. In which layer would you incorporate the processing code? – Shady Shahin Jan 04 '24 at 18:26
  • We need a method for the infrastructure layer to send incoming messages from the communication protocols to the domain layer, where these messages can be processed to enforce business rules in the domain layer. – Shady Shahin Jan 04 '24 at 18:28
  • what about my sample code doesnt work for you? – Ewan Jan 04 '24 at 18:45
  • Do you mean that I will keep listening for any incoming data from the Infrastructure layer? Which layer should process the above code or that logic? – Shady Shahin Jan 04 '24 at 18:55
  • Well, I would call it the application layer. at some point you have to put all your layers together into some process that gets run. and that has to reference everything – Ewan Jan 04 '24 at 19:31
  • @candied_orange's latest diagram shows the program flow well, you come in on the infra layer with the IncomingClient, run the domain layer DataProcessor, then go out again on the Infrastructure layers OutgoingClient – Ewan Jan 04 '24 at 19:56