Search code examples
c#business-logics#arp-architecture

S#arp Architecture: Where to put this domain logic


re: S#arp Architecture

A bit of a noob question about where to put certain sorts of domain logic with S#arp. OK, so imagine this domain rule:

When asking for a specific chat room by name, return the room if it already exists, or else create a new one with that name and return it.

Is this Domain Logic? In which case, how do I implement it in my Entity object (as I seem to need access to the Repository to do it)

Is this Controller Logic? In which case I guess I stick it in the MVC controller, easy enough.

Is this Data Access Logic? In which case I build it into the Repository object and the Contoller calls it. Again, easy enough.

I reckon this is Domain Logic, but then I'm not sure how to built it into my Entity. As Entities dont seem to access to Repositories (or am I missing something?).


Solution

  • From the way you've described it, I'd say this would best go in the Application Services layer. (the Tasks layer in the WhoCanHelpMe? example project). For me this is application logic rather than domain logic.

    For the other options:

    • Sharp is designed intentionally so that Entities don't access the Repositories. (You'll find quite a lot of articles around on why Entities should be persistence-ignorant.)
    • In general the controllers aren't really meant to contain any business logic directly - for readability, testability, etc. (Personally I'm comfortable putting logic in there initially and then refactoring it out.)

    One reason I'd be uncomfortable putting the logic directly in a repository is clarity. If you have methods on IChatRoomRepository:

    ChatRoom GetRoomByName (string name);
    ChatRoom GetRoomById (int id);
    

    typically GetRoomById would return null if there is no room for the given id, so it's not too obvious that the first method will silently create (and presumably persist?) a room if you don't already have one.

    More conceptually, from DDD Quickly (p56):

    We should not mix a Repository with a Factory. The Factory should create new objects, while the Repository should find already created objects. When a new object is to be added to the Repository, it should be created first using the Factory, and then it should be given to the Repository

    which would suggest that if you're trying to implement the repository pattern, the creation of a new chat room should happen outside the repository.