-1

I'm experimenting with some projects at the moment and I am stuck trying to decide on the correct approach to this question.

Given a simple architecture like this consisting of

Domain - (Person and IPersonService)

public class Person
{
   public string Name { get; set; }
   public string PhoneNumber { get; set; }
   public string ImageUrl { get; set; }
}

public interface IPersonService
{
   void Save(Person person);
   Person GetById(string id);
}

Infrastructure - (PersonService) -> Database

public class PersonService
{
   void Save(Person person)
   {
     //Save to DB
   }

   Person GetById(string id)
   {
      return //FROM DB
   }
}

UI

There is now a requirement to allow the user to search for an image with some UX around it , select an image and we populate the imageUrl on the Person record. The imageservice will be a server side http call to some thirdparty image API which we will then return to our UI.

My question is where should this IImageService live?

To me it doesn't make sense to live in the Domain because the domain doesn't care about it. Although it could.

The ImageService is going to require some additional models etc too.

Do these all live in the Infrastructure or UI? Or do we need an additional project UI.Services?

I may be overthinking it but just curious what others think. enter image description here

2
  • Why is the ImageUrl not enough for the Person class? Who needs to fetch the image from the image service? Commented Jan 4, 2023 at 21:22
  • 1
    Anemic domain models are an anti-pattern in DDD or any proper object oriented approach for that matter. Start by creating classes based on behavior and give them the properties to support that behavior. Btw. Get and Save methods do not belong in the domain layer, those are infrastructure concerns.
    – Rik D
    Commented Jan 4, 2023 at 21:26

1 Answer 1

0

My question is where should this IImageService live?

In the application layer.

Think of this layer as an overlay. Everything in this layer is meant to allow users to discover your business and enrich it. You can enhance and enrich your business with additional features that are application dependant. Images are useless in CLI apps, but almost a must-have on web or phone apps. Right?

To me it doesn't make sense to live in the Domain because the domain doesn't care about it. Although it could.

Fair enough. You don't want images messing with the domain. So, what can you do?

Data overlay or data composition whatever you like most. It only takes a new table in your database pointing USER table via FK1 and the file path of the image in your file system. The new table is managed by the application. The code belongs to the application layer. Moreover, the application layer might provide with its own UserService which orchestrate the calls to domain.UserService and ImageService, just for transactionability (if required).

So, expand your design allowing more layers. Or rearrange the current one in such a way it makes the expansion possible2. You can have as many layers as boundaries you deem necessary. The given three are very very limiting and will fall short. Eventually.

The key then is at implementing a consistent dependency. Regarding this matter, you might find interesting the stable dependency principle.


1: Uncle Bob stable dependency in action but this time driven by DB constraints.

2: It might interest you a different code organization. For example, package-by-feature instead of package-by-layer.

2
  • Thank you for all the responses. Been reading up alot more on DDD and clean architecture and got my head round it now. Came to the same conclusion Application is where it belongs which was completely missing on my example. Commented Jan 7, 2023 at 0:07
  • This answer uses a subtly different scenario than OP. From OP's code I infer that the service is going to effectively convert "the image" to an URL (by uploading it to the appropriate cloud storage), and then add this URL to the person rather than a separate table. I don't disagree with the overall need for an Application layer here, but specifically uploading to a third party storage is something that belongs in Infrastructure. That being said, calling said image repo and updating the person accordingly is indeed part of the Application logic, but not the third party connection itself.
    – Flater
    Commented Jun 6, 2023 at 23:10

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.