rohbau 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8d05d28272851e7d359b3640cdb9e4a21250f704
4
+ data.tar.gz: 183ca9c967b841d7dc8e4bc6dbdd57e222eab5fc
5
+ SHA512:
6
+ metadata.gz: 9b144522c39a33baa618b912f17e3f9a2a6f743a910194cc052409cd890992a0994eb629da418eb5b5d8cb1816f64159f944c9daada4b55546b1b58f71a86529
7
+ data.tar.gz: 9e6e8cd4e34c668c81172180d3ca99b64af7d5b32e9b1d19a35a72c420e2ad15eda820b0c122f6529bb2a946fe56c0a1d7dbc854bb5b4e458791edfd661e96f7
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ Gemfile.lock
data/.travis.yml ADDED
@@ -0,0 +1,27 @@
1
+ language: ruby
2
+ sudo: false
3
+ cache: bundler
4
+ rvm:
5
+ - ruby-head
6
+ - 2.2
7
+ - 2.1
8
+ - 2.0
9
+ - 1.9.3
10
+ - jruby
11
+ - jruby-head
12
+ - jruby-19mode # JRuby in 1.9 mode
13
+ env:
14
+ global:
15
+ - JRUBY_OPTS='--dev -J-Xmx1024M'
16
+ matrix:
17
+ fast_finish: true
18
+ allow_failures:
19
+ - rvm: ruby-head
20
+ - rvm: jruby-head
21
+ notifications:
22
+ webhooks:
23
+ urls:
24
+ - https://webhooks.gitter.im/e/c6efc69df9417bda7808
25
+ on_success: change # options: [always|never|change] default: always
26
+ on_failure: always # options: [always|never|change] default: always
27
+ on_start: false # default: false
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rohbau.gemspec
4
+ gemspec
5
+
6
+ if ENV['CODECLIMATE_REPO_TOKEN']
7
+ gem "codeclimate-test-reporter", :group => :test, :require => nil
8
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,189 @@
1
+ [github]: https://github.com/neopoly/rohbau
2
+ [doc]: http://rubydoc.info/github/neopoly/rohbau/master/file/README.md
3
+ [gem]: https://rubygems.org/gems/rohbau
4
+ [gem-badge]: https://img.shields.io/gem/v/rohbau.svg
5
+ [travis]: https://travis-ci.org/neopoly/rohbau
6
+ [travis-badge]: https://img.shields.io/travis/neopoly/rohbau.svg?branch=master
7
+ [codeclimate]: https://codeclimate.com/github/neopoly/rohbau
8
+ [codeclimate-climate-badge]: https://img.shields.io/codeclimate/github/neopoly/rohbau.svg
9
+ [codeclimate-coverage-badge]: https://codeclimate.com/github/neopoly/rohbau/badges/coverage.svg
10
+ [inchpages]: https://inch-ci.org/github/neopoly/rohbau
11
+ [inchpages-badge]: https://inch-ci.org/github/neopoly/rohbau.svg?branch=master&style=flat
12
+
13
+ # Rohbau
14
+
15
+ [![Travis][travis-badge]][travis]
16
+ [![Gem Version][gem-badge]][gem]
17
+ [![Code Climate][codeclimate-climate-badge]][codeclimate]
18
+ [![Test Coverage][codeclimate-coverage-badge]][codeclimate]
19
+ [![Inline docs][inchpages-badge]][inchpages]
20
+
21
+ [Gem][gem] |
22
+ [Source][github] |
23
+ [Documentation][doc]
24
+
25
+ ## Description
26
+
27
+ Rohbau provides a set of patterns used in Domain Driven Design.
28
+
29
+ ## Installation
30
+
31
+ Add this line to your application's Gemfile:
32
+
33
+ gem 'rohbau'
34
+
35
+ And then execute:
36
+
37
+ $ bundle
38
+
39
+ Or install it yourself as:
40
+
41
+ $ gem install rohbau
42
+
43
+ ## Usage
44
+
45
+ ### Runtime
46
+
47
+ By instantiation of the `RuntimeLoader`, an instance of the `Runtime`is created and stored as a singleton.
48
+ Internal units of the respective component can access this instance by referring to the `RuntimeLoader`.
49
+ By this a place is made where for example memories for in-memory gateway backend implementations can be stored.
50
+
51
+ #### Examples
52
+
53
+ Inject a user service to your application
54
+
55
+ ```ruby
56
+ require 'rohbau/runtime'
57
+ require 'rohbau/runtime_loader'
58
+
59
+ module MyApplication
60
+ class RuntimeLoader < Rohbau::RuntimeLoader
61
+ def initialize
62
+ super(Runtime)
63
+ end
64
+ end
65
+
66
+ class Runtime < Rohbau::Runtime
67
+ end
68
+ end
69
+
70
+ module UserService
71
+ class RuntimeLoader < Rohbau::RuntimeLoader
72
+ def initialize
73
+ super(Runtime)
74
+ end
75
+ end
76
+
77
+ class Runtime < Rohbau::Runtime
78
+ end
79
+ end
80
+
81
+ # Register user service on my application runtime
82
+ MyApplication::Runtime.register :user_service, UserService::RuntimeLoader
83
+ MyApplication::Runtime.plugins # => {:user_service=>UserService::RuntimeLoader}
84
+
85
+ # Runtimes are not initialized yet
86
+ MyApplication::RuntimeLoader.instance # => nil
87
+ MyApplication::Runtime.plugins[:user_service].instance # => nil
88
+
89
+ # Boot my application runtime
90
+ MyApplication::RuntimeLoader.running? # => false
91
+ MyApplication::RuntimeLoader.new
92
+ MyApplication::RuntimeLoader.running? # => true
93
+
94
+ # Runtimes are initialized
95
+ MyApplication::RuntimeLoader.instance # => #<MyApplication::Runtime:0x00000000f5b8d8 @user_service=UserService::RuntimeLoader>
96
+ MyApplication::Runtime.plugins[:user_service].instance # => #<UserService::Runtime:0x00000000b1ecc0>
97
+
98
+ # Runtimes are singletons
99
+ MyApplication::RuntimeLoader.instance === MyApplication::RuntimeLoader.instance
100
+ MyApplication::Runtime.plugins[:user_service].instance === MyApplication::Runtime.plugins[:user_service].instance
101
+
102
+ # Terminate my application runtime
103
+ MyApplication::RuntimeLoader.terminate
104
+ MyApplication::RuntimeLoader.running? # => false
105
+
106
+ ```
107
+
108
+ ##### Registrar
109
+
110
+ Every injected `RuntimeLoader` knows about it's registrar.
111
+ In the example above `UserService::RuntimeLoader` has been injected to `MyApplication::RuntimeLoader`.
112
+ `UserService::RuntimeLoader.registrar` therefore returns `MyApplication::RuntimeLoader`.
113
+
114
+ ##### List of plugins
115
+
116
+ Accordingly to the sample above `MyApplication::RuntimeLoader` knows about it's registered plugins.
117
+ `MyApplication::RuntimeLoader.plugins` therefore returns `{:user_service => UserService::RuntimeLoader}`.
118
+
119
+ ### ServiceFactory
120
+
121
+ The `ServiceFactory` is considered the authority for retrieval of service instances.
122
+ It follows partly the service locator / registry pattern.
123
+
124
+ #### Examples
125
+
126
+ Register and unregister default service and override with specific service.
127
+
128
+ ```ruby
129
+ require 'rohbau/service_factory'
130
+
131
+ MyServiceFactory = Class.new(Rohbau::ServiceFactory)
132
+
133
+ user_service_1 = Struct.new(:users).new([:alice, :bob])
134
+ user_service_2 = Struct.new(:users).new([:jim, :kate])
135
+
136
+ runtime = Object.new
137
+ registry = MyServiceFactory.new(runtime)
138
+
139
+ MyServiceFactory.register(:user_service) { user_service_1 }
140
+ registry.user_service.users # => [:alice, :bob]
141
+
142
+ MyServiceFactory.register(:user_service) { user_service_2 }
143
+ registry.user_service.users # => [:jim, :kate]
144
+
145
+ MyServiceFactory.unregister(:user_service)
146
+ registry.user_service.users # => [:alice, :bob]
147
+
148
+ MyServiceFactory.unregister(:user_service)
149
+ registry.user_service # => NoMethodError: undefined method `user_service'
150
+
151
+ ```
152
+
153
+ Validate registered dependencies
154
+
155
+ ```ruby
156
+ MyServiceFactory.external_dependencies :user_service
157
+ MyServiceFactory.missing_dependencies # => [:user_service]
158
+ MyServiceFactory.external_dependencies_complied? # => false
159
+
160
+ MyServiceFactory.register(:user_service) { Object.new } # => :user_service
161
+ MyServiceFactory.external_dependencies_complied? # => true
162
+ MyServiceFactory.missing_dependencies # => []
163
+ ```
164
+
165
+ ## Build README
166
+
167
+ Make changes to README.md.template, not to README.md
168
+
169
+ Include examples with
170
+
171
+ ```bash
172
+ include_example example_file_name
173
+ ```
174
+
175
+ Build README.md with
176
+
177
+ ```bash
178
+ ./bin/build_readme
179
+ ```
180
+
181
+ Always commit README.md.template and README.md together.
182
+
183
+ ## Contributing
184
+
185
+ 1. Fork it
186
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
187
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
188
+ 4. Push to the branch (`git push origin my-new-feature`)
189
+ 5. Create new Pull Request
@@ -0,0 +1,119 @@
1
+ [github]: https://github.com/neopoly/rohbau
2
+ [doc]: http://rubydoc.info/github/neopoly/rohbau/master/file/README.md
3
+ [gem]: https://rubygems.org/gems/rohbau
4
+ [gem-badge]: https://img.shields.io/gem/v/rohbau.svg
5
+ [travis]: https://travis-ci.org/neopoly/rohbau
6
+ [travis-badge]: https://img.shields.io/travis/neopoly/rohbau.svg?branch=master
7
+ [codeclimate]: https://codeclimate.com/github/neopoly/rohbau
8
+ [codeclimate-climate-badge]: https://img.shields.io/codeclimate/github/neopoly/rohbau.svg
9
+ [codeclimate-coverage-badge]: https://codeclimate.com/github/neopoly/rohbau/badges/coverage.svg
10
+ [inchpages]: https://inch-ci.org/github/neopoly/rohbau
11
+ [inchpages-badge]: https://inch-ci.org/github/neopoly/rohbau.svg?branch=master&style=flat
12
+
13
+ # Rohbau
14
+
15
+ [![Travis][travis-badge]][travis]
16
+ [![Gem Version][gem-badge]][gem]
17
+ [![Code Climate][codeclimate-climate-badge]][codeclimate]
18
+ [![Test Coverage][codeclimate-coverage-badge]][codeclimate]
19
+ [![Inline docs][inchpages-badge]][inchpages]
20
+
21
+ [Gem][gem] |
22
+ [Source][github] |
23
+ [Documentation][doc]
24
+
25
+ ## Description
26
+
27
+ Rohbau provides a set of patterns used in Domain Driven Design.
28
+
29
+ ## Installation
30
+
31
+ Add this line to your application's Gemfile:
32
+
33
+ gem 'rohbau'
34
+
35
+ And then execute:
36
+
37
+ $ bundle
38
+
39
+ Or install it yourself as:
40
+
41
+ $ gem install rohbau
42
+
43
+ ## Usage
44
+
45
+ ### Runtime
46
+
47
+ By instantiation of the `RuntimeLoader`, an instance of the `Runtime`is created and stored as a singleton.
48
+ Internal units of the respective component can access this instance by referring to the `RuntimeLoader`.
49
+ By this a place is made where for example memories for in-memory gateway backend implementations can be stored.
50
+
51
+ #### Examples
52
+
53
+ Inject a user service to your application
54
+
55
+ ```ruby
56
+ include_example runtime
57
+ ```
58
+
59
+ ##### Registrar
60
+
61
+ Every injected `RuntimeLoader` knows about it's registrar.
62
+ In the example above `UserService::RuntimeLoader` has been injected to `MyApplication::RuntimeLoader`.
63
+ `UserService::RuntimeLoader.registrar` therefore returns `MyApplication::RuntimeLoader`.
64
+
65
+ ##### List of plugins
66
+
67
+ Accordingly to the sample above `MyApplication::RuntimeLoader` knows about it's registered plugins.
68
+ `MyApplication::RuntimeLoader.plugins` therefore returns `{:user_service => UserService::RuntimeLoader}`.
69
+
70
+ ### ServiceFactory
71
+
72
+ The `ServiceFactory` is considered the authority for retrieval of service instances.
73
+ It follows partly the service locator / registry pattern.
74
+
75
+ #### Examples
76
+
77
+ Register and unregister default service and override with specific service.
78
+
79
+ ```ruby
80
+ include_example service_factory
81
+ ```
82
+
83
+ Validate registered dependencies
84
+
85
+ ```ruby
86
+ MyServiceFactory.external_dependencies :user_service
87
+ MyServiceFactory.missing_dependencies # => [:user_service]
88
+ MyServiceFactory.external_dependencies_complied? # => false
89
+
90
+ MyServiceFactory.register(:user_service) { Object.new } # => :user_service
91
+ MyServiceFactory.external_dependencies_complied? # => true
92
+ MyServiceFactory.missing_dependencies # => []
93
+ ```
94
+
95
+ ## Build README
96
+
97
+ Make changes to README.md.template, not to README.md
98
+
99
+ Include examples with
100
+
101
+ ```bash
102
+ include_example example_file_name
103
+ ```
104
+
105
+ Build README.md with
106
+
107
+ ```bash
108
+ ./bin/build_readme
109
+ ```
110
+
111
+ Always commit README.md.template and README.md together.
112
+
113
+ ## Contributing
114
+
115
+ 1. Fork it
116
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
117
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
118
+ 4. Push to the branch (`git push origin my-new-feature`)
119
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:spec) do |t|
5
+ t.libs += ['spec', 'lib']
6
+ t.test_files = FileList['spec/**/*_spec.rb']
7
+ t.verbose = true
8
+ end
9
+
10
+ task :default => :spec
data/bin/build_readme ADDED
@@ -0,0 +1 @@
1
+ cat README.md.template | etc/build_readme.rb > README.md
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ template = $stdin.read
4
+ examples = template.scan(/include_example (.*)/).flatten
5
+
6
+ examples.each do |example|
7
+ file = "examples/#{example}.rb"
8
+ if File.exists?(file)
9
+ replacement = File.read(file)
10
+ template.gsub!(/include_example #{example}/, replacement)
11
+ end
12
+ end
13
+
14
+ $stdout.print template
@@ -0,0 +1,49 @@
1
+ require 'rohbau/runtime'
2
+ require 'rohbau/runtime_loader'
3
+
4
+ module MyApplication
5
+ class RuntimeLoader < Rohbau::RuntimeLoader
6
+ def initialize
7
+ super(Runtime)
8
+ end
9
+ end
10
+
11
+ class Runtime < Rohbau::Runtime
12
+ end
13
+ end
14
+
15
+ module UserService
16
+ class RuntimeLoader < Rohbau::RuntimeLoader
17
+ def initialize
18
+ super(Runtime)
19
+ end
20
+ end
21
+
22
+ class Runtime < Rohbau::Runtime
23
+ end
24
+ end
25
+
26
+ # Register user service on my application runtime
27
+ MyApplication::Runtime.register :user_service, UserService::RuntimeLoader
28
+ MyApplication::Runtime.plugins # => {:user_service=>UserService::RuntimeLoader}
29
+
30
+ # Runtimes are not initialized yet
31
+ MyApplication::RuntimeLoader.instance # => nil
32
+ MyApplication::Runtime.plugins[:user_service].instance # => nil
33
+
34
+ # Boot my application runtime
35
+ MyApplication::RuntimeLoader.running? # => false
36
+ MyApplication::RuntimeLoader.new
37
+ MyApplication::RuntimeLoader.running? # => true
38
+
39
+ # Runtimes are initialized
40
+ MyApplication::RuntimeLoader.instance # => #<MyApplication::Runtime:0x00000000f5b8d8 @user_service=UserService::RuntimeLoader>
41
+ MyApplication::Runtime.plugins[:user_service].instance # => #<UserService::Runtime:0x00000000b1ecc0>
42
+
43
+ # Runtimes are singletons
44
+ MyApplication::RuntimeLoader.instance === MyApplication::RuntimeLoader.instance
45
+ MyApplication::Runtime.plugins[:user_service].instance === MyApplication::Runtime.plugins[:user_service].instance
46
+
47
+ # Terminate my application runtime
48
+ MyApplication::RuntimeLoader.terminate
49
+ MyApplication::RuntimeLoader.running? # => false
@@ -0,0 +1,21 @@
1
+ require 'rohbau/service_factory'
2
+
3
+ MyServiceFactory = Class.new(Rohbau::ServiceFactory)
4
+
5
+ user_service_1 = Struct.new(:users).new([:alice, :bob])
6
+ user_service_2 = Struct.new(:users).new([:jim, :kate])
7
+
8
+ runtime = Object.new
9
+ registry = MyServiceFactory.new(runtime)
10
+
11
+ MyServiceFactory.register(:user_service) { user_service_1 }
12
+ registry.user_service.users # => [:alice, :bob]
13
+
14
+ MyServiceFactory.register(:user_service) { user_service_2 }
15
+ registry.user_service.users # => [:jim, :kate]
16
+
17
+ MyServiceFactory.unregister(:user_service)
18
+ registry.user_service.users # => [:alice, :bob]
19
+
20
+ MyServiceFactory.unregister(:user_service)
21
+ registry.user_service # => NoMethodError: undefined method `user_service'
@@ -0,0 +1,11 @@
1
+ require 'rohbau/service_factory'
2
+
3
+ MyServiceFactory = Class.new(Rohbau::ServiceFactory)
4
+
5
+ MyServiceFactory.external_dependencies :user_service
6
+ MyServiceFactory.missing_dependencies # => [:user_service]
7
+ MyServiceFactory.external_dependencies_complied? # => false
8
+
9
+ MyServiceFactory.register(:user_service) { Object.new } # => :user_service
10
+ MyServiceFactory.external_dependencies_complied? # => true
11
+ MyServiceFactory.missing_dependencies # => []
@@ -0,0 +1,70 @@
1
+ module Rohbau
2
+ module Application
3
+
4
+ class RuntimeWrapper
5
+ def self.wrap(&constructor)
6
+ wrapper = Class.new do
7
+ def self.set_constructor(constructor)
8
+ @constructor = constructor
9
+ self
10
+ end
11
+
12
+ def self.new(*ignored_args)
13
+ @constructor.call
14
+ end
15
+ end
16
+
17
+ wrapper.set_constructor(constructor)
18
+ end
19
+ end
20
+
21
+ def set_application_runtime(runtime_class)
22
+ @runtime_class = runtime_class
23
+ end
24
+
25
+ def register_domain(name, namespace)
26
+ dummy = RuntimeWrapper.wrap do |cls|
27
+ namespace::Runtime.start
28
+ end
29
+
30
+ @runtime_class.register name, dummy
31
+
32
+ domains << namespace
33
+ end
34
+
35
+ def domains
36
+ @domains ||= []
37
+ end
38
+
39
+ def domain_requests
40
+ domains.map{|d| d.const_get :Request }
41
+ end
42
+
43
+ def use_case_domains
44
+ domains.select do |domain|
45
+ domain.const_defined?('UseCases')
46
+ end
47
+ end
48
+
49
+ def use_cases(use_case_domain = :all)
50
+ if use_case_domain == :all
51
+ domains = use_case_domains
52
+ else
53
+ domains = [use_case_domain]
54
+ end
55
+
56
+ domains.inject([]) do |use_cases, domain|
57
+
58
+ if domain.const_defined?('UseCases')
59
+ use_case_namespace = domain.const_get('UseCases')
60
+ use_case_namespace.constants.each do |use_case_class_name|
61
+ use_cases << use_case_namespace::const_get(use_case_class_name)
62
+ end
63
+ end
64
+
65
+ use_cases
66
+ end
67
+ end
68
+
69
+ end
70
+ end
@@ -0,0 +1,78 @@
1
+ require 'rohbau/index'
2
+
3
+ module Rohbau
4
+ class DefaultMemoryGateway
5
+
6
+ def initialize(memory = Index.new, services = {})
7
+ @memory = memory
8
+ @services = services
9
+ end
10
+
11
+ def memory
12
+ @memory
13
+ end
14
+
15
+ def add(entity)
16
+ @memory.add entity
17
+ end
18
+
19
+ def bulk_add(*entities)
20
+ @memory.bulk_add(*entities)
21
+ end
22
+
23
+ def get(uid)
24
+ @memory.get(uid)
25
+ end
26
+
27
+ def update(entity)
28
+ @memory.update(entity)
29
+ end
30
+
31
+ def delete(uid)
32
+ @memory.delete(uid)
33
+ end
34
+
35
+ def bulk_delete(*uids)
36
+ @memory.bulk_delete(*uids)
37
+ end
38
+
39
+ def all
40
+ @memory.all
41
+ end
42
+
43
+ def size
44
+ @memory.size
45
+ end
46
+
47
+ protected
48
+
49
+ def service(service_name)
50
+ @services[service_name] || raise(no_service_error service_name)
51
+ end
52
+
53
+ def no_service_error(service_name)
54
+ NotImplementedError.new("#{service_name} service in #{self.class}")
55
+ end
56
+
57
+ def map(entity_name, entity)
58
+ gateway = gateway_for_entity(entity_name)
59
+
60
+ if entity.uid
61
+ result = gateway.update(entity)
62
+ else
63
+ result = gateway.add(entity)
64
+ end
65
+
66
+ result.uid
67
+ end
68
+
69
+ def unmap(entity_name, uid)
70
+ gateway_for_entity(entity_name).get(uid)
71
+ end
72
+
73
+ def gateway_for_entity(entity_name)
74
+ service(:"#{entity_name}_gateway")
75
+ end
76
+
77
+ end
78
+ end
@@ -0,0 +1,41 @@
1
+ module Rohbau
2
+
3
+ class Entity
4
+ class << self; attr_accessor :__attributes__ end
5
+ def self.attributes(*attributes)
6
+ @__attributes__ ||= []
7
+ @__attributes__ += attributes
8
+
9
+
10
+ predicate_attributes = attributes.select do |attr|
11
+ attr =~ /\?$/
12
+ end
13
+
14
+ regular_attributes = attributes - predicate_attributes
15
+
16
+ predicate_attributes.each do |attribute|
17
+ attribute_without_predicate = attribute.to_s.gsub(/\?$/, '')
18
+ attr_accessor attribute_without_predicate
19
+
20
+ define_method attribute do ||
21
+ !!instance_variable_get(:"@#{attribute_without_predicate}")
22
+ end
23
+ end
24
+
25
+ attr_accessor(*regular_attributes)
26
+ end
27
+
28
+ def ==(other)
29
+ other && __attributes__.all? do |attr|
30
+ other.respond_to?(attr) &&
31
+ self.public_send(attr) == other.public_send(attr)
32
+ end
33
+ end
34
+
35
+ protected
36
+ def __attributes__
37
+ self.class.__attributes__ || []
38
+ end
39
+ end
40
+
41
+ end