midnight-business_logic 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/midnight/business_logic.rb +19 -0
- data/lib/midnight/business_logic/aggregate_root.rb +46 -0
- data/lib/midnight/business_logic/event.rb +47 -0
- data/lib/midnight/business_logic/event_dispatcher.rb +69 -0
- data/lib/midnight/business_logic/version.rb +5 -0
- data/lib/midnight/commons/concurrent_write_error.rb +8 -0
- data/lib/midnight/commons/constants.rb +5 -0
- metadata +64 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 24cfcc468f4e7e48f77e50e2728017a106ea7a07703aa11d939781766eb5ad61
|
4
|
+
data.tar.gz: 36e4bcb84ec676b5cdb6ddd3523ec08d43630573bc9bf9602315c01db1694f75
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0ab18cc817a8aaf3d1bbc3d4d1b7bf389de5bc91f1bbb33d673571c1402c7503b1b636316e8c846770f60d8b7a7ce8486d1fe9bb47683c282b7c94bb3006b026
|
7
|
+
data.tar.gz: fa3cdba82a930e1759665d7e13f287001f589fbdbcc84fed14625007fba5c289dc4270c4a56d70a620de2d7a6580d90c8796c5eb4e1e2a9c6a39632b5604dabc
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'active_support/dependencies/autoload'
|
2
|
+
require_relative 'business_logic/version'
|
3
|
+
|
4
|
+
module Midnight
|
5
|
+
module Commons
|
6
|
+
extend ::ActiveSupport::Autoload
|
7
|
+
|
8
|
+
autoload :ConcurrentWriteError
|
9
|
+
autoload :NULL_EVENT_HANDLER, 'midnight/commons/constants'
|
10
|
+
end
|
11
|
+
|
12
|
+
module BusinessLogic
|
13
|
+
extend ::ActiveSupport::Autoload
|
14
|
+
|
15
|
+
autoload :AggregateRoot
|
16
|
+
autoload :Event
|
17
|
+
autoload :EventDispatcher
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Midnight
|
4
|
+
module BusinessLogic
|
5
|
+
module AggregateRoot
|
6
|
+
class UnknownCommand < ArgumentError
|
7
|
+
end
|
8
|
+
|
9
|
+
extend ::ActiveSupport::Concern
|
10
|
+
|
11
|
+
def dispatch(_command)
|
12
|
+
raise UnknownCommand
|
13
|
+
end
|
14
|
+
|
15
|
+
def state
|
16
|
+
@state ||= {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def pending_events
|
20
|
+
@pending_events ||= []
|
21
|
+
end
|
22
|
+
|
23
|
+
class_methods do
|
24
|
+
attr_accessor :_event_handlers
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def on(event_class, &block)
|
29
|
+
self._event_handlers ||= {}
|
30
|
+
self._event_handlers[event_class] = block
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def apply(*events)
|
37
|
+
handlers = self.class._event_handlers || {}
|
38
|
+
events.each do |event|
|
39
|
+
handler = handlers[event.class]
|
40
|
+
instance_exec(event, &handler) if handler
|
41
|
+
pending_events << event
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'time'
|
2
|
+
require 'active_support/core_ext/time'
|
3
|
+
|
4
|
+
module Midnight
|
5
|
+
module BusinessLogic
|
6
|
+
class Event
|
7
|
+
class SchemaViolation < ArgumentError
|
8
|
+
end
|
9
|
+
|
10
|
+
DEFAULT_METADATA_GENERATOR = lambda do
|
11
|
+
{
|
12
|
+
occurred_at: ::Time.current.iso8601(6)
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(data: {}, metadata: nil)
|
17
|
+
@data = data
|
18
|
+
@metadata = metadata || DEFAULT_METADATA_GENERATOR.call
|
19
|
+
freeze
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :data, :metadata
|
23
|
+
|
24
|
+
class << self
|
25
|
+
def strict(data: {}, metadata: nil)
|
26
|
+
ensure_schema(data)
|
27
|
+
new(
|
28
|
+
data: data,
|
29
|
+
metadata: metadata
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def ensure_schema(_data)
|
36
|
+
raise NotImplementedError
|
37
|
+
# example
|
38
|
+
# @data_schema ||= ::Dry::Schema.Params do
|
39
|
+
# required(:example_field).filled(:string)
|
40
|
+
# end
|
41
|
+
# result = @data_schema.call(data)
|
42
|
+
# raise SchemaViolation unless result.success?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'active_support/core_ext/object/blank'
|
2
|
+
|
3
|
+
module Midnight
|
4
|
+
module BusinessLogic
|
5
|
+
class EventDispatcher
|
6
|
+
class InvalidHandlerSupplied < ArgumentError
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(handlers_map = {})
|
10
|
+
handlers_map.each do |_event_class, handler_list|
|
11
|
+
handler_list.each do |handler|
|
12
|
+
raise InvalidHandlerSupplied unless handler.respond_to?(:call)
|
13
|
+
# correct construction example:
|
14
|
+
# EventDispatcher.new(SomeEvent => [
|
15
|
+
# method(:puts)
|
16
|
+
# ])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
@_handlers_map = handlers_map
|
20
|
+
freeze
|
21
|
+
end
|
22
|
+
|
23
|
+
def once(event)
|
24
|
+
handler_list = @_handlers_map[event.class]
|
25
|
+
unless handler_list.blank?
|
26
|
+
handler_list.each do |handler|
|
27
|
+
handler.call(event)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def batch(events)
|
33
|
+
events.each(&method(:once))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class CompositeEventDispatcher # quack like EventDispatcher
|
38
|
+
def initialize(*dispatchers)
|
39
|
+
@_dispatchers = dispatchers
|
40
|
+
freeze
|
41
|
+
end
|
42
|
+
|
43
|
+
def once(event)
|
44
|
+
@_dispatchers.each do |dispatcher|
|
45
|
+
dispatcher.once(event)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def batch(events)
|
50
|
+
events.each(&method(:once))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
private_constant :CompositeEventDispatcher
|
54
|
+
|
55
|
+
class EventDispatcher
|
56
|
+
class InvalidDispatcherSupplied < ArgumentError;
|
57
|
+
end
|
58
|
+
|
59
|
+
class << self
|
60
|
+
def merge(*dispatchers)
|
61
|
+
raise InvalidDispatcherSupplied unless dispatchers.all? do |dispatcher|
|
62
|
+
dispatcher.respond_to?(:once)
|
63
|
+
end
|
64
|
+
CompositeEventDispatcher.new(*dispatchers)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: midnight-business_logic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sarun Rattanasiri
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-08-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: Midnight::BusinessLogic is a toolkit for writing clean and robust business
|
28
|
+
logics agnostic to frameworks, user interfaces, and data storage. Make the business
|
29
|
+
logic fully testable and provides isolation from external side effects.
|
30
|
+
email: midnight_w@gmx.tw
|
31
|
+
executables: []
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- lib/midnight/business_logic.rb
|
36
|
+
- lib/midnight/business_logic/aggregate_root.rb
|
37
|
+
- lib/midnight/business_logic/event.rb
|
38
|
+
- lib/midnight/business_logic/event_dispatcher.rb
|
39
|
+
- lib/midnight/business_logic/version.rb
|
40
|
+
- lib/midnight/commons/concurrent_write_error.rb
|
41
|
+
- lib/midnight/commons/constants.rb
|
42
|
+
homepage: https://gitlab.com/slime-systems/midnight-enterprise-toolkit/tree/master/midnight-business_logic
|
43
|
+
licenses: []
|
44
|
+
metadata: {}
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
requirements: []
|
60
|
+
rubygems_version: 3.0.3
|
61
|
+
signing_key:
|
62
|
+
specification_version: 4
|
63
|
+
summary: A toolkit for writing enterprise business logic
|
64
|
+
test_files: []
|