Derek
Derek

Reputation: 8630

Event Sourcing Event typed against an Aggregate

enter code here I'm looking to enforce the specific type of aggregate, an event can be used with.

I have a basic IEventHandler interface :-

  public interface IEventHandler<TEvent> where TEvent : IEvent
    {
        void Handle(TEvent @event);
    }

The Event Base class inherits from this :-

public class Event : IEvent
    {
        #region Constructors

        public Event(Guid aggregateRootId)
        {
            Timestamp = DateTime.Now;
            Id = Guid.NewGuid();
            AggregateRootId = aggregateRootId;

        }

        #endregion

        #region Implementation of IEvent<Guid,Guid>

        public Guid Id { get; private set; }

        public Guid AggregateRootId { get; private set; }

        public int Version { get; set; }
        public DateTime Timestamp { get; private set; }

        #endregion
    }

Now I need to make my Aggregate or Class specific Event :-

  public class ClientNameChangedEvent : Event
        {
            #region Constructors

            public ClientNameChangedEvent(Guid aggregateRootId, string name, int version) : base(aggregateRootId)
            {
                Name = name;
                Version = version;
            }

            #endregion

            #region Properties

            public string Name { get; private set; }

            #endregion
        }

As the name suggests, I only want to use this against the Client aggregate. I want a way to prevent the programmer registering the event, from associating it against another Aggregate, In the example below, Ive registered an Interest in the client Events against a Case Aggregate.

public class Case : AggregateRoot, IEventHandler<ClientNameChangedEvent>
    {

        #region Properties
        public string Name { get; private set; }

        #endregion

        public Case()
        {

        }

        public Case(Guid id, string name) : base(id)
        {

        }

        public void ChangeName(string name)
        {
            if (!Name.ToUpper().Equals(name.ToUpper()))
            {
                ApplyChange(new ClientNameChangedEvent(Id, name, Version));
            }
        }

        public void Handle(ClientNameChangedEvent @event)
        {
            Name = @event.Name;
            Version = @event.Version + 1;
        }

        public void Handle(ClientCreatedEvent @event)
        {
            Id = @event.AggregateRootId;
            Name = @event.Name;
            Version = @event.Version;
        }
    }
}

How can I prevent this?

Upvotes: 0

Views: 135

Answers (1)

Codescribler
Codescribler

Reputation: 2305

Events are tied to a particular aggregate by the aggregateId. When you prepare an aggregate you load it's previous events via the id. You then apply all the past events associated to that id (assuming no snapshot) to the aggregate.

The subscription to events is not on the domain side but on read side. Multiple denormalisers can 'handle' any one event.

For a little more in depth overview of the flow take a look at my post: CQRS Step-By-Step Guide to the Flow of a Typical Application.

Good luck - I hope it helps

Upvotes: 0

Related Questions