rddd 0.1.0 → 0.1.1
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.
- data/Gemfile.lock +1 -1
- data/lib/rddd.rb +16 -2
- data/lib/rddd/aggregate_root.rb +8 -6
- data/lib/rddd/aggregate_root_finders.rb +9 -7
- data/lib/rddd/configuration.rb +21 -0
- data/lib/rddd/entity.rb +1 -1
- data/lib/rddd/repository.rb +1 -1
- data/lib/rddd/repository_factory.rb +16 -12
- data/lib/rddd/service.rb +1 -1
- data/lib/rddd/service_bus.rb +50 -48
- data/lib/rddd/service_factory.rb +13 -8
- data/lib/rddd/version.rb +1 -1
- data/spec/integration_spec.rb +3 -3
- data/spec/lib/aggregate_root_spec.rb +6 -6
- data/spec/lib/entity_spec.rb +4 -4
- data/spec/lib/repository_factory_spec.rb +16 -6
- data/spec/lib/repository_spec.rb +1 -1
- data/spec/lib/service_bus_spec.rb +7 -7
- data/spec/lib/service_factory_spec.rb +15 -5
- data/spec/lib/service_spec.rb +4 -4
- data/spec/spec_helper.rb +1 -0
- metadata +2 -1
data/Gemfile.lock
CHANGED
data/lib/rddd.rb
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
-
require
|
1
|
+
require 'rddd/version'
|
2
|
+
require 'rddd/configuration'
|
2
3
|
|
3
|
-
module Rddd
|
4
|
+
module Rddd
|
5
|
+
#
|
6
|
+
# Configure Rddd framework.
|
7
|
+
#
|
8
|
+
# ## Usage
|
9
|
+
#
|
10
|
+
# Rddd.configure do |config|
|
11
|
+
# config.services_namespace = Rddd::Services
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
def self.configure
|
15
|
+
yield(Rddd::Configuration.instance)
|
16
|
+
end
|
17
|
+
end
|
data/lib/rddd/aggregate_root.rb
CHANGED
@@ -2,14 +2,16 @@ require 'rddd/entity'
|
|
2
2
|
require 'rddd/repository_factory'
|
3
3
|
require 'rddd/aggregate_root_finders'
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
module Rddd
|
6
|
+
class AggregateRoot < Entity
|
7
|
+
extend AggregateRootFinders
|
7
8
|
|
8
|
-
|
9
|
+
finder :find_by_id
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
[:create, :update, :delete].each do |action|
|
12
|
+
define_method action do
|
13
|
+
self.class.repository.send(action, self)
|
14
|
+
end
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
@@ -1,11 +1,13 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module Rddd
|
2
|
+
module AggregateRootFinders
|
3
|
+
def finder(name)
|
4
|
+
define_singleton_method name do |*args|
|
5
|
+
repository.send(name, *args)
|
6
|
+
end
|
5
7
|
end
|
6
|
-
end
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
def repository
|
10
|
+
RepositoryFactory.build(self)
|
11
|
+
end
|
10
12
|
end
|
11
13
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
#
|
4
|
+
# Use configuration to configure internals of the RDDD
|
5
|
+
# framework.
|
6
|
+
#
|
7
|
+
module Rddd
|
8
|
+
class Configuration
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
attr_writer :services_namespace, :repositories_namespace
|
12
|
+
|
13
|
+
def services_namespace
|
14
|
+
@services_namespace || Object
|
15
|
+
end
|
16
|
+
|
17
|
+
def repositories_namespace
|
18
|
+
@repositories_namespace || Object
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/rddd/entity.rb
CHANGED
data/lib/rddd/repository.rb
CHANGED
@@ -1,18 +1,22 @@
|
|
1
1
|
require 'rddd/repository'
|
2
|
+
require 'rddd/configuration'
|
2
3
|
|
3
|
-
|
4
|
-
|
4
|
+
module Rddd
|
5
|
+
class NotExistingRepository < RuntimeError
|
6
|
+
end
|
5
7
|
|
6
|
-
class RepositoryFactory
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
begin
|
11
|
-
repository = const_get(repository_name)
|
12
|
-
rescue
|
13
|
-
raise NotExistingRepository unless repository
|
14
|
-
end
|
8
|
+
class RepositoryFactory
|
9
|
+
def self.build(clazz)
|
10
|
+
repository_name = "#{clazz.name.split('::').last}Repository"
|
11
|
+
ns = Configuration.instance.repositories_namespace
|
15
12
|
|
16
|
-
|
13
|
+
begin
|
14
|
+
repository = ns.const_get(repository_name)
|
15
|
+
rescue
|
16
|
+
raise NotExistingRepository unless repository
|
17
|
+
end
|
18
|
+
|
19
|
+
repository.new
|
20
|
+
end
|
17
21
|
end
|
18
22
|
end
|
data/lib/rddd/service.rb
CHANGED
data/lib/rddd/service_bus.rb
CHANGED
@@ -1,57 +1,59 @@
|
|
1
1
|
require 'rddd/service_factory'
|
2
2
|
|
3
|
-
|
3
|
+
module Rddd
|
4
|
+
class InvalidService < RuntimeError; end
|
4
5
|
|
5
|
-
#
|
6
|
-
# Service bus is the central entry point for execution of service within the
|
7
|
-
# domain layer. Unless you have a very good reason, services should not be
|
8
|
-
# instantiated directly outside the domain layer, as you leave the flexibility
|
9
|
-
# on domain itself to choose the correct implementation.
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# ## Usage
|
13
|
-
#
|
14
|
-
# Service bus as the module could be included to any object which intend to
|
15
|
-
# call services within the domain layer.
|
16
|
-
#
|
17
|
-
#
|
18
|
-
# ## Example
|
19
|
-
#
|
20
|
-
# class ProjectsController
|
21
|
-
# include ServiceBus
|
22
|
-
#
|
23
|
-
# def create
|
24
|
-
# execute(:create_project, params) do |errors|
|
25
|
-
# render :new, :errors => errors
|
26
|
-
# return
|
27
|
-
# end
|
28
|
-
#
|
29
|
-
# redirect_to projects_path, :notice => 'Project was successfully created!'
|
30
|
-
# end
|
31
|
-
# end
|
32
|
-
#
|
33
|
-
#
|
34
|
-
module ServiceBus
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
6
|
+
#
|
7
|
+
# Service bus is the central entry point for execution of service within the
|
8
|
+
# domain layer. Unless you have a very good reason, services should not be
|
9
|
+
# instantiated directly outside the domain layer, as you leave the flexibility
|
10
|
+
# on domain itself to choose the correct implementation.
|
11
|
+
#
|
12
|
+
#
|
13
|
+
# ## Usage
|
14
|
+
#
|
15
|
+
# Service bus as the module could be included to any object which intend to
|
16
|
+
# call services within the domain layer.
|
17
|
+
#
|
18
|
+
#
|
19
|
+
# ## Example
|
20
|
+
#
|
21
|
+
# class ProjectsController
|
22
|
+
# include ServiceBus
|
23
|
+
#
|
24
|
+
# def create
|
25
|
+
# execute(:create_project, params) do |errors|
|
26
|
+
# render :new, :errors => errors
|
27
|
+
# return
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# redirect_to projects_path, :notice => 'Project was successfully created!'
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
#
|
35
|
+
module ServiceBus
|
36
|
+
#
|
37
|
+
# Execute the given service.
|
38
|
+
#
|
39
|
+
# @param {Symbol} Service to be executed.
|
40
|
+
# @param {Hash} Attributes to be passed to the service call.
|
41
|
+
# @param {Block} Optional error callback block.
|
42
|
+
#
|
43
|
+
def execute(service_name, attributes = {})
|
44
|
+
raise InvalidService unless service = build_service(service_name, attributes)
|
44
45
|
|
45
|
-
|
46
|
-
|
47
|
-
|
46
|
+
unless service.valid?
|
47
|
+
yield(service.errors) and return if block_given?
|
48
|
+
end
|
48
49
|
|
49
|
-
|
50
|
-
|
50
|
+
service.execute
|
51
|
+
end
|
51
52
|
|
52
|
-
|
53
|
+
private
|
53
54
|
|
54
|
-
|
55
|
-
|
55
|
+
def build_service(service_name, attributes)
|
56
|
+
ServiceFactory.build(service_name, attributes)
|
57
|
+
end
|
56
58
|
end
|
57
59
|
end
|
data/lib/rddd/service_factory.rb
CHANGED
@@ -1,12 +1,17 @@
|
|
1
|
-
|
2
|
-
def self.build(name, attributes)
|
3
|
-
class_name = "#{camel_case(name.to_s)}Service"
|
1
|
+
require 'rddd/configuration'
|
4
2
|
|
5
|
-
|
6
|
-
|
3
|
+
module Rddd
|
4
|
+
class ServiceFactory
|
5
|
+
def self.build(name, attributes)
|
6
|
+
class_name = "#{camel_case(name.to_s)}Service"
|
7
|
+
ns = Configuration.instance.services_namespace
|
8
|
+
|
9
|
+
ns.const_get(class_name.to_sym).new(attributes)
|
10
|
+
end
|
7
11
|
|
8
|
-
|
9
|
-
|
10
|
-
|
12
|
+
def self.camel_case(string)
|
13
|
+
return string if string !~ /_/ && string =~ /[A-Z]+.*/
|
14
|
+
string.split('_').map{|e| e.capitalize}.join
|
15
|
+
end
|
11
16
|
end
|
12
17
|
end
|
data/lib/rddd/version.rb
CHANGED
data/spec/integration_spec.rb
CHANGED
@@ -4,11 +4,11 @@ require 'rddd/aggregate_root'
|
|
4
4
|
require 'rddd/service_bus'
|
5
5
|
require 'rddd/service'
|
6
6
|
|
7
|
-
class Project < AggregateRoot
|
7
|
+
class Project < Rddd::AggregateRoot
|
8
8
|
attr_accessor :name
|
9
9
|
end
|
10
10
|
|
11
|
-
class CreateProjectService < Service
|
11
|
+
class CreateProjectService < Rddd::Service
|
12
12
|
def execute
|
13
13
|
project = Project.new(@attributes[:id])
|
14
14
|
project.name = @attributes[:name]
|
@@ -24,7 +24,7 @@ class ProjectRepository
|
|
24
24
|
end
|
25
25
|
|
26
26
|
class ProjectsController
|
27
|
-
include ServiceBus
|
27
|
+
include Rddd::ServiceBus
|
28
28
|
|
29
29
|
def create(params)
|
30
30
|
execute(:create_project, params)
|
@@ -1,22 +1,22 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rddd/aggregate_root'
|
3
3
|
|
4
|
-
describe AggregateRoot do
|
4
|
+
describe Rddd::AggregateRoot do
|
5
5
|
let(:id) { stub('id') }
|
6
6
|
|
7
|
-
let(:aggregate_root) { AggregateRoot.new(id) }
|
7
|
+
let(:aggregate_root) { Rddd::AggregateRoot.new(id) }
|
8
8
|
|
9
9
|
it 'should be entity' do
|
10
|
-
aggregate_root.should be_kind_of Entity
|
10
|
+
aggregate_root.should be_kind_of Rddd::Entity
|
11
11
|
end
|
12
12
|
|
13
13
|
describe '#find_by_id' do
|
14
|
-
subject { AggregateRoot.find_by_id(id) }
|
14
|
+
subject { Rddd::AggregateRoot.find_by_id(id) }
|
15
15
|
|
16
16
|
let(:repository) { stub('repository') }
|
17
17
|
|
18
18
|
before {
|
19
|
-
RepositoryFactory.expects(:build).returns(repository)
|
19
|
+
Rddd::RepositoryFactory.expects(:build).returns(repository)
|
20
20
|
repository.expects(:find_by_id).with(id)
|
21
21
|
}
|
22
22
|
|
@@ -30,7 +30,7 @@ describe AggregateRoot do
|
|
30
30
|
let(:repository) { stub('repository') }
|
31
31
|
|
32
32
|
it 'should call #create on repository' do
|
33
|
-
RepositoryFactory.expects(:build).with(AggregateRoot).returns(repository)
|
33
|
+
Rddd::RepositoryFactory.expects(:build).with(Rddd::AggregateRoot).returns(repository)
|
34
34
|
|
35
35
|
repository.expects(action).with(subject)
|
36
36
|
|
data/spec/lib/entity_spec.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rddd/entity'
|
3
3
|
|
4
|
-
describe Entity do
|
4
|
+
describe Rddd::Entity do
|
5
5
|
it 'should have identity' do
|
6
|
-
entity = Entity.new('1234')
|
6
|
+
entity = Rddd::Entity.new('1234')
|
7
7
|
|
8
8
|
entity.id.should == '1234'
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'two entities with same identity are equal' do
|
12
|
-
a = Entity.new('1234')
|
13
|
-
b = Entity.new('1234')
|
12
|
+
a = Rddd::Entity.new('1234')
|
13
|
+
b = Rddd::Entity.new('1234')
|
14
14
|
|
15
15
|
(a == b).should be_true
|
16
16
|
end
|
@@ -2,23 +2,33 @@ require 'spec_helper'
|
|
2
2
|
require 'rddd/entity'
|
3
3
|
require 'rddd/repository_factory'
|
4
4
|
|
5
|
-
describe RepositoryFactory do
|
5
|
+
describe Rddd::RepositoryFactory do
|
6
6
|
describe '.build' do
|
7
|
-
subject { RepositoryFactory.build(Entity) }
|
7
|
+
subject { Rddd::RepositoryFactory.build(Rddd::Entity) }
|
8
8
|
|
9
9
|
context 'with existing repository' do
|
10
|
-
before
|
10
|
+
before do
|
11
|
+
Rddd.const_set(:Repositories, Module.new)
|
12
|
+
Rddd::Repositories.const_set(:EntityRepository, Class.new)
|
11
13
|
|
12
|
-
|
14
|
+
Rddd.configure { |config| config.repositories_namespace = Rddd::Repositories }
|
15
|
+
end
|
16
|
+
|
17
|
+
after do
|
18
|
+
Rddd::Repositories.class_eval {remove_const(:EntityRepository)}
|
19
|
+
Rddd.class_eval {remove_const(:Repositories)}
|
20
|
+
|
21
|
+
Rddd.configure { |config| config.repositories_namespace = Object }
|
22
|
+
end
|
13
23
|
|
14
24
|
it 'should return instance of repository' do
|
15
|
-
should be_kind_of EntityRepository
|
25
|
+
should be_kind_of Rddd::Repositories::EntityRepository
|
16
26
|
end
|
17
27
|
end
|
18
28
|
|
19
29
|
context 'with not existing repository' do
|
20
30
|
it 'should raise NotExistingRepository' do
|
21
|
-
lambda { subject }.should raise_exception NotExistingRepository
|
31
|
+
lambda { subject }.should raise_exception Rddd::NotExistingRepository
|
22
32
|
end
|
23
33
|
end
|
24
34
|
end
|
data/spec/lib/repository_spec.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rddd/service_bus'
|
3
3
|
|
4
|
-
describe ServiceBus do
|
4
|
+
describe Rddd::ServiceBus do
|
5
5
|
let(:attributes) { stub('attributes') }
|
6
6
|
|
7
7
|
let(:controller) do
|
8
|
-
stub('controller').tap { |controller| controller.extend ServiceBus }
|
8
|
+
stub('controller').tap { |controller| controller.extend Rddd::ServiceBus }
|
9
9
|
end
|
10
10
|
|
11
11
|
describe '.execute' do
|
@@ -15,7 +15,7 @@ describe ServiceBus do
|
|
15
15
|
|
16
16
|
context 'existing service' do
|
17
17
|
it do
|
18
|
-
ServiceFactory.expects(:build).with(:foo, attributes).returns(service)
|
18
|
+
Rddd::ServiceFactory.expects(:build).with(:foo, attributes).returns(service)
|
19
19
|
service.expects(:execute)
|
20
20
|
|
21
21
|
subject
|
@@ -24,10 +24,10 @@ describe ServiceBus do
|
|
24
24
|
|
25
25
|
context 'not-existing service' do
|
26
26
|
it do
|
27
|
-
ServiceFactory.expects(:build).with(:foo, attributes).returns(nil)
|
27
|
+
Rddd::ServiceFactory.expects(:build).with(:foo, attributes).returns(nil)
|
28
28
|
service.expects(:execute).never
|
29
29
|
|
30
|
-
lambda { subject }.should raise_exception InvalidService
|
30
|
+
lambda { subject }.should raise_exception Rddd::InvalidService
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -36,7 +36,7 @@ describe ServiceBus do
|
|
36
36
|
before { service.stubs(:valid?).returns(false) }
|
37
37
|
|
38
38
|
it do
|
39
|
-
ServiceFactory.expects(:build).with(:foo, attributes).returns(service)
|
39
|
+
Rddd::ServiceFactory.expects(:build).with(:foo, attributes).returns(service)
|
40
40
|
service.expects(:execute).never
|
41
41
|
|
42
42
|
subject
|
@@ -54,7 +54,7 @@ describe ServiceBus do
|
|
54
54
|
let(:error_block) { lambda {|errors|} }
|
55
55
|
|
56
56
|
it do
|
57
|
-
ServiceFactory.expects(:build).with(:foo, attributes).returns(service)
|
57
|
+
Rddd::ServiceFactory.expects(:build).with(:foo, attributes).returns(service)
|
58
58
|
service.expects(:execute).never
|
59
59
|
|
60
60
|
controller.execute(:foo, attributes, &error_block)
|
@@ -1,18 +1,28 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rddd/service_factory'
|
3
3
|
|
4
|
-
describe ServiceFactory do
|
4
|
+
describe Rddd::ServiceFactory do
|
5
5
|
let(:attributes) { stub('attributes') }
|
6
6
|
|
7
|
-
before
|
7
|
+
before do
|
8
|
+
Rddd.const_set(:Services, Module.new)
|
9
|
+
Rddd::Services.const_set(:CreateProjectService, Class.new)
|
8
10
|
|
9
|
-
|
11
|
+
Rddd.configure { |config| config.services_namespace = Rddd::Services }
|
12
|
+
end
|
13
|
+
|
14
|
+
after do
|
15
|
+
Rddd::Services.class_eval {remove_const(:CreateProjectService)}
|
16
|
+
Rddd.class_eval {remove_const(:Services)}
|
17
|
+
|
18
|
+
Rddd.configure { |config| config.services_namespace = Object }
|
19
|
+
end
|
10
20
|
|
11
21
|
describe '.build' do
|
12
22
|
it do
|
13
|
-
CreateProjectService.expects(:new).with(attributes)
|
23
|
+
Rddd::Services::CreateProjectService.expects(:new).with(attributes)
|
14
24
|
|
15
|
-
ServiceFactory.build(:create_project, attributes)
|
25
|
+
Rddd::ServiceFactory.build(:create_project, attributes)
|
16
26
|
end
|
17
27
|
end
|
18
28
|
end
|
data/spec/lib/service_spec.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rddd/service'
|
3
3
|
|
4
|
-
describe Service do
|
4
|
+
describe Rddd::Service do
|
5
5
|
let(:attributes) { stub('attributes') }
|
6
6
|
|
7
7
|
describe '#initialize' do
|
8
|
-
subject { Service.new(attributes) }
|
8
|
+
subject { Rddd::Service.new(attributes) }
|
9
9
|
|
10
10
|
it 'should store attributes' do
|
11
11
|
subject.instance_variable_get(:@attributes).should == attributes
|
@@ -13,14 +13,14 @@ describe Service do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
describe '#valid?' do
|
16
|
-
subject { Service.new.valid? }
|
16
|
+
subject { Rddd::Service.new.valid? }
|
17
17
|
it { should be_true }
|
18
18
|
end
|
19
19
|
|
20
20
|
describe '#execute' do
|
21
21
|
it 'should raise not implemented' do
|
22
22
|
lambda do
|
23
|
-
Service.new(attributes).execute
|
23
|
+
Rddd::Service.new(attributes).execute
|
24
24
|
end.should raise_exception(NotImplementedError)
|
25
25
|
end
|
26
26
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rddd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -29,6 +29,7 @@ files:
|
|
29
29
|
- lib/rddd.rb
|
30
30
|
- lib/rddd/aggregate_root.rb
|
31
31
|
- lib/rddd/aggregate_root_finders.rb
|
32
|
+
- lib/rddd/configuration.rb
|
32
33
|
- lib/rddd/entity.rb
|
33
34
|
- lib/rddd/repository.rb
|
34
35
|
- lib/rddd/repository_factory.rb
|