Class: FourthDimensional::Repository
- Inherits:
-
Object
- Object
- FourthDimensional::Repository
- Defined in:
- lib/fourth_dimensional/repository.rb
Overview
FourthDimensional::Repository
Event sourcing is a good application for the repository pattern since we need to have a single source track commands and events being applied to the system.
The FourthDimensional::Repository is a wrapper around loading and persisting events/commands with dependency injection. This allows new repositories to be defined and easily registered.
The loading and persisting of events/commands are separated to allow separating the reading and writing databases should that become necessary.
class InMemoryEvents
attr_reader :events
def initialize
@events = []
end
def self.instance
@instance ||= InMemoryEvents.new
end
end
class InMemoryEventLoader
def for_aggregate(aggregate_id)
InMemoryEvents.events
.filter { |event| event.aggregate_id == aggregate_id }
end
def save_commands_and_events(commands:, events:)
InMemoryEvents.events.concat(events)
end
end
FourthDimensional.configure do |config|
config.event_loader = InMemoryEventLoader.new
end
Instance Attribute Summary collapse
-
#applied_events ⇒ Object
readonly
An array of events saved.
-
#called_commands ⇒ Object
readonly
An array of commands called.
-
#event_loader ⇒ Object
readonly
The source to load events.
Instance Method Summary collapse
-
#events_for_aggregate(aggregate_id) ⇒ Object
Delegates to event_loader#for_aggregate.
-
#initialize(event_loader:) ⇒ Repository
constructor
A new instance of Repository.
-
#load_aggregate(aggregate_class, aggregate_id) ⇒ Object
Loads events from
event_loader
and applies them to a new instance ofaggregate_class
. -
#save_command_and_events(command_and_events) ⇒ Object
Saves the command and events with the
event_loader
.
Constructor Details
#initialize(event_loader:) ⇒ Repository
Returns a new instance of Repository.
51 52 53 54 55 |
# File 'lib/fourth_dimensional/repository.rb', line 51 def initialize(event_loader:) @event_loader = event_loader @applied_events = [] @called_commands = [] end |
Instance Attribute Details
#applied_events ⇒ Object (readonly)
An array of events saved
46 47 48 |
# File 'lib/fourth_dimensional/repository.rb', line 46 def applied_events @applied_events end |
#called_commands ⇒ Object (readonly)
An array of commands called
49 50 51 |
# File 'lib/fourth_dimensional/repository.rb', line 49 def called_commands @called_commands end |
#event_loader ⇒ Object (readonly)
The source to load events
43 44 45 |
# File 'lib/fourth_dimensional/repository.rb', line 43 def event_loader @event_loader end |
Instance Method Details
#events_for_aggregate(aggregate_id) ⇒ Object
Delegates to event_loader#for_aggregate
FourthDimensional.repository.events_for_aggregate(aggregate_id)
60 61 62 |
# File 'lib/fourth_dimensional/repository.rb', line 60 def events_for_aggregate(aggregate_id) event_loader.for_aggregate(aggregate_id) end |
#load_aggregate(aggregate_class, aggregate_id) ⇒ Object
Loads events from event_loader
and applies them to a new instance of aggregate_class
FourthDimensional.repository.load_aggregate(PostAggregate, aggregate_id) # => PostAggregate
68 69 70 71 72 73 74 |
# File 'lib/fourth_dimensional/repository.rb', line 68 def load_aggregate(aggregate_class, aggregate_id) events_for_aggregate(aggregate_id) .reduce(aggregate_class.new(id: aggregate_id)) do |aggregate, event| aggregate.apply_existing_event(event) aggregate end end |
#save_command_and_events(command_and_events) ⇒ Object
Saves the command and events with the event_loader
repository.save_command_and_events(FourthDimensional::CommandHandler::CommandAndEvents.new(
command: AddPost,
events: [PostAdded]
))
82 83 84 85 |
# File 'lib/fourth_dimensional/repository.rb', line 82 def save_command_and_events(command_and_events) called_commands << command_and_events.command applied_events.concat(command_and_events.events) end |