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_loaderand 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 |