Several Domain Drive Design questions

87 Views Asked by At

Lately I am trying to learn DDD and I am working on a test project. I have a few questions conserning my code. I just want to clarify that the meantions of Event in this code snippet refer to concerts, conferences, etc. It has no relation with DomainEvents, delegates or anything like that:

public class EventsDomainService : IEventsDomainService
{
    private readonly IEventFactory _eventFactory;
    private readonly IEventsRepository _eventsRepository;

    public EventsDomainService(IEventsRepository eventsRepository, IEventFactory eventFactory)
    {
        _eventFactory = eventFactory;
        _eventsRepository = eventsRepository;
    }

    public async Task<Event> CreateEvent(Guid id, string name, DateTime startsAt, short durationHrs, Guid organizerId, Guid venueId, byte minAge, EventType type, bool isAvailable)
    {
        var @event = _eventFactory
                .Builder(id, name, new Organizer(organizerId), new Venue(venueId), startsAt, type)
                .WithDuration(durationHrs)
                .WithMinAge(minAge)
                .WithIsAvailable(isAvailable)
                .Build();
        await _eventsRepository.Insert(@event);
        return @event;
    }
}
  • The repo interface is part of the domain but the concrete implementaiton is in the infrastrcture layer. Is this the correct approach?

  • Creating an event is part of the real life domain so as I understand DDD the creation of an event is a responsibility of the domain service. Am I correct? I am wondering because it only calls the factory and persists. Should it be in the application service maybe? Or maybe the constructor should be used instead of the replace the service's method and also call the repository?

  • Also as you can see from the factory, the event aggregate has an Organizer entity. Do I need an Organizer entity object that is just an Id or can I get away with just a Guid field. ALso, if the Organizer was a more complex entity, for instance it had a name, how should I approach it?

Thanks in advance.

1

There are 1 best solutions below

0
On

The repo interface is part of the domain but the concrete implementaiton is in the infrastrcture layer. Is this the correct approach?

Correct

Creating an event is part of the real life domain so as I understand DDD the creation of an event is a responsibility of the domain service. Am I correct? I am wondering because it only calls the factory and persists. Should it be in the application service maybe? Or maybe the constructor should be used instead of the replace the service's method and also call the repository?

You are confusing creating and constructing the event. This is why I prefer say the domain layer raises events and infrastructure layer instantiate them (like a factory). Like for the previous question, consider IEventsDomainService in the domain layer and EventsDomainService in the infrastrcture layer. In the interface, the domain layer provides values for the event. In the implementation you can persist them into your event sourcing persistence mechanism, send them to a MQ service for CQRS handling, or post them to twitter if you want.

Also as you can see from the factory, the event aggregate has an Organizer entity. Do I need an Organizer entity object that is just an Id or can I get away with just a Guid field. ALso, if the Organizer was a more complex entity, for instance it had a name, how should I approach it?

An event is a change in the domain state. It is not the state itself, so an event cannot be an aggregate per se. That you store events as ORM mapped objects in the same RDBMS as aggregates is not a design constraint. You could send them to an MQ without persisting them for instance, and still persist your aggregates in an ORM accessed RDBMS.

Consider event implementation as an infrastructure concern. If you use event sourcing, you will have a repository reconstructing the aggregate state from the events, but it's like restoring a file content from a series of delta patches: returning business value from a write optimized physical model.