sinject 0.2.4 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: db6745bbf4a6fd9f3355de4ebdc1b1a8ff9baac2
4
- data.tar.gz: 5e595fc791ed9ed491df2cc49359cf821641f6ac
2
+ SHA256:
3
+ metadata.gz: 74d73c7073d972685d7102f6760e326669637d897330058adec4d32acf28e192
4
+ data.tar.gz: 92c467b5781f2893261c602b676c3cc84263886e5f44ddf7cb1540d18b8d0602
5
5
  SHA512:
6
- metadata.gz: 88674605b4a9265fa8e2835fc4dd4dadb02be1535feff9ae5f863fcd799563483753f8056505fb7bba2d282e901fab766bb23a08a36100d10b496efcc2f4611b
7
- data.tar.gz: f7d5be771710b45ba3d3fa6dc5aa9674faf96037a60d4cda3e850572deff3657d71eb6f2d739fcc1255de7330592e5550a7438e12f4a05ecd0dbabf6cde13297
6
+ metadata.gz: cdfdd548a9ac9befbfeb94f0a9ac7ff5456b68746af2183764cb4593656c03f42c5bdb81cf108c6aaacf5129a0bc1ef3fe82505d24ff5c79e43a4aeabdf4f4b9
7
+ data.tar.gz: aa2b989d31dc8ad7939e7d20228cdabb05adc68c694198391364e675e53b820beba258e3e68d9fb7b4199c7fed51d9ee09a7e3b56899cf2fcc5fa061dfe462e2
data/lib/sinject.rb CHANGED
@@ -1,249 +1,5 @@
1
- require "sinject/version"
2
-
3
-
4
- #This is the IOC Container for registering all dependencies an building objects.
5
- class SinjectContainer
6
-
7
- class << self
8
- attr_accessor :instance
9
- end
10
-
11
- def initialize
12
- @store = []
13
- SinjectContainer.instance = self
14
- end
15
-
16
- # Check if an object has been registered with the container.
17
- #
18
- # Example:
19
- # >> SinjectContainer.instance.is_registered? :object_key
20
- # => true
21
- #
22
- # Arguments:
23
- # key: (Symbol)
24
- def is_registered?(key)
25
- !@store.select { |i| i.key == key}.empty?
26
- end
27
-
28
- # Register an object with the container.
29
- # Objects can be registered as either a single instance or a multi instance object.
30
- # Single instance objects are only initialized once and the same object is returned from the container for every request.
31
- # Multi instance objects are a new instance that is created for each request.
32
- #
33
- # Example:
34
- # >> SinjectContainer.instance.register :object_key, ClassName, true, ContractName
35
- #
36
- # Arguments:
37
- # key: (Symbol)
38
- # class_name: (ClassName)
39
- # single_instance: (Boolean)
40
- def register(key, dependency_class_name, single_instance = false, contract_class_name = nil, &initialize_block)
41
-
42
- #check if a dependency has already been registered for this key.
43
- if is_registered?(key)
44
- raise DependencyRegistrationException.new(key)
45
- end
46
-
47
- #check if a contract has been specified
48
- if contract_class_name != nil
49
- #validate the dependency class against the contract
50
- validate_contract(dependency_class_name, contract_class_name)
51
- end
52
-
53
- item = ContainerItem.new
54
- item.key = key
55
- item.single_instance = single_instance
56
- item.class_name = dependency_class_name
57
- item.initialize_block = initialize_block
58
-
59
- @store.push(item)
60
- end
61
-
62
- # Get an object from the container.
63
- # This will build the requested object and all its dependencies.
64
- #
65
- # Example:
66
- # >> SinjectContainer.instance.get :object_key
67
- #
68
- # Arguments:
69
- # key: (Symbol)
70
- def get(key)
71
- #get the dependency from the container store for the specified key
72
- items = @store.select { |i| i.key == key}
73
- if !items.empty?
74
- item = items.first
75
-
76
- #check if the item has been registered as a single instance item.
77
- if item.single_instance == true
78
- #check if the instance needs to be created
79
- if item.instance == nil
80
- item.instance = create_instance(item)
81
- end
82
- return item.instance
83
- else
84
- return create_instance(item)
85
- end
86
- else
87
- #no dependency has been registered for the specified key, attempt to convert the key into a class name and initialize it.
88
- class_name = "#{key}".split('_').collect(&:capitalize).join
89
- Object.const_get(class_name).new
90
- end
91
- end
92
-
93
- def load_groups
94
- DependencyGroup.descendants.each do |g|
95
- group = g.new
96
- if group.is_valid?
97
- group.register(SinjectContainer.instance)
98
- end
99
- end
100
- end
101
-
102
- private
103
-
104
- def validate_contract(dependency_class, contract_class)
105
-
106
- #get the methods defined for the contract
107
- contract_methods = (contract_class.instance_methods - Object.instance_methods)
108
- #get the methods defined for the dependency
109
- dependency_methods = (dependency_class.instance_methods - Object.instance_methods)
110
- #calculate any methods specified in the contract that are not specified in the dependency
111
- missing_methods = contract_methods - dependency_methods
112
-
113
- if !missing_methods.empty?
114
- raise DependencyContractMissingMethodsException.new(missing_methods)
115
- end
116
-
117
- #loop through each contract method
118
- contract_methods.each do |method|
119
-
120
- #get the contract method parameters
121
- cmp = contract_class.instance_method(method).parameters
122
- #get teh dependency method parameters
123
- dmp = dependency_class.instance_method(method).parameters
124
-
125
- #check if the parameters match for both methods
126
- if cmp != dmp
127
- raise DependencyContractInvalidParametersException.new(method, cmp)
128
- end
129
-
130
- end
131
-
132
- end
133
-
134
- def create_instance(item)
135
- instance = nil
136
-
137
- #check if a custom initializer block has been specified
138
- if item.initialize_block != nil
139
- #call the block to create the dependency instance
140
- instance = item.initialize_block.call
141
-
142
- #verify the block created the expected dependency type
143
- if !instance.is_a?(item.class_name)
144
- raise DependencyInitializeException.new(item.class_name)
145
- end
146
- else
147
- instance = item.class_name.new
148
- end
149
-
150
- instance
151
- end
152
- end
153
-
154
- class ContainerItem
155
- attr_accessor :key
156
- attr_accessor :instance
157
- attr_accessor :single_instance
158
- attr_accessor :class_name
159
- attr_accessor :initialize_block
160
- end
161
-
162
- class Class
163
-
164
- # Specify a dependency required by a class.
165
- # This will create an attribute for the required dependency that will be populated by the ioc container.
166
- #
167
- # Example:
168
- # >> dependency :registered_object_symbol
169
- #
170
- # Arguments:
171
- # key: (Symbol)
172
- def dependency(*obj_key)
173
- obj_key.each do |k|
174
-
175
- self.send(:define_method, k) do
176
- val = self.instance_variable_get("@#{k}")
177
- if(val == nil)
178
- val = SinjectContainer.instance.get(k)
179
- self.instance_variable_set("@#{k}", val)
180
- end
181
- val
182
- end
183
-
184
- end
185
- end
186
- end
187
-
188
- class DependencyContractMissingMethodsException < StandardError
189
- def initialize(methods)
190
- @methods = methods
191
- end
192
-
193
- def to_s
194
- method_names = @methods.join(', ')
195
- "The following methods have not been implemented: '#{method_names}'"
196
- end
197
- end
198
-
199
- class DependencyContractInvalidParametersException < StandardError
200
- def initialize(method, parameters)
201
- @method = method
202
- @parameters = parameters
203
- end
204
-
205
- def to_s
206
- parameter_names = @parameters.join(', ')
207
- "The method signature of method: '#{@method}' does not match the contract parameters: '#{parameter_names}'"
208
- end
209
- end
210
-
211
- class DependencyInitializeException < StandardError
212
-
213
- def initialize(expected_type)
214
- @expected_type = expected_type
215
- end
216
-
217
- def to_s
218
- "The custom dependency initializer does not return an object of the expected type: '#{@expected_type}'"
219
- end
220
-
221
- end
222
-
223
- class DependencyRegistrationException < StandardError
224
-
225
- def initialize(key)
226
- @key = key
227
- end
228
-
229
- def to_s
230
- "A Dependency has already been registered for the key: '#{key}'"
231
- end
232
-
233
- end
234
-
235
- class DependencyGroup
236
-
237
- def register(container)
238
-
239
- end
240
-
241
- def is_valid?
242
- return true
243
- end
244
-
245
- def self.descendants
246
- ObjectSpace.each_object(Class).select { |klass| klass < self }
247
- end
248
-
249
- end
1
+ require 'sinject/class'
2
+ require 'sinject/container'
3
+ require 'sinject/container_item'
4
+ require 'sinject/dependency_group'
5
+ require 'sinject/exceptions'
@@ -0,0 +1,25 @@
1
+ class Class
2
+
3
+ # Specify a dependency required by a class.
4
+ # This will create an attribute for the required dependency that will be populated by the ioc container.
5
+ #
6
+ # Example:
7
+ # >> dependency :registered_object_symbol
8
+ #
9
+ # Arguments:
10
+ # key: (Symbol)
11
+ def dependency(*obj_key)
12
+ obj_key.each do |k|
13
+
14
+ self.send(:define_method, k) do
15
+ val = self.instance_variable_get("@#{k}")
16
+ if(val == nil)
17
+ val = Sinject::Container.instance.get(k)
18
+ self.instance_variable_set("@#{k}", val)
19
+ end
20
+ val
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,191 @@
1
+ module Sinject
2
+ #This is the IOC Container for registering all dependencies an building objects.
3
+ class Container
4
+
5
+ class << self
6
+ attr_accessor :instance
7
+ end
8
+
9
+ def initialize(singleton=true)
10
+ @store = {}
11
+ Sinject::Container.instance = self if singleton
12
+ end
13
+
14
+ # Check if an object has been registered with the container.
15
+ #
16
+ # Example:
17
+ # >> Sinject::Container.instance.registered? :object_key
18
+ # => true
19
+ #
20
+ # Arguments:
21
+ # key: (Symbol)
22
+ def registered?(key)
23
+ @store.has_key?(key)
24
+ end
25
+ # @deprecated: Use registered? method instead
26
+ def is_registered?(key)
27
+ puts "[#{self.class}] - #is_registered? method is deprecated please use #registered? instead."
28
+ registered?(key)
29
+ end
30
+
31
+ # Register an object with the container.
32
+ # Objects can be registered as either a single instance or a multi instance object.
33
+ # Single instance objects are only initialized once and the same object is returned from the container for every request.
34
+ # Multi instance objects are a new instance that is created for each request.
35
+ #
36
+ # Example:
37
+ # >> Sinject::Container.instance.register { :key => :object_key, :class => ClassName, :singleton => true, :contract => ContractName }
38
+ #
39
+ # Arguments:
40
+ # key: (Symbol)
41
+ # class_name: (ClassName)
42
+ # single_instance: (Boolean)
43
+ def register(options = {}, &initialize_block)
44
+ raise Sinject::DependencyRegistrationKeyNotSpecifiedException.new unless options.has_key?(:key)
45
+
46
+ raise Sinject::DependencyRegistrationClassNotSpecifiedException.new unless options.has_key?(:class)
47
+
48
+ key = options[:key]
49
+ dependency_class_name = options[:class]
50
+
51
+ # check if a dependency has already been registered for this key.
52
+ raise Sinject::DependencyRegistrationException.new(key) if registered?(key)
53
+
54
+ single_instance = false
55
+ contract_class_name = nil
56
+
57
+ if options != nil && options[:singleton] == true
58
+ single_instance = true
59
+ end
60
+
61
+ if options != nil && options[:contract] != nil
62
+ contract_class_name = options[:contract]
63
+ end
64
+
65
+ # Validate the dependency class against the contract if a contract has been specified
66
+ validate_contract(dependency_class_name, contract_class_name) unless contract_class_name.nil?
67
+
68
+ item = Sinject::ContainerItem.new
69
+ item.key = key
70
+ item.single_instance = single_instance
71
+ item.class_name = dependency_class_name
72
+ item.initialize_block = initialize_block
73
+
74
+ @store[item.key] = item
75
+ true
76
+ end
77
+
78
+ # Get an object from the container.
79
+ # This will build the requested object and all its dependencies.
80
+ #
81
+ # Example:
82
+ # >> Sinject::Container.instance.get :object_key
83
+ #
84
+ # Arguments:
85
+ # key: (Symbol)
86
+ def get(key)
87
+ # get the dependency from the container store for the specified key
88
+ item = @store[key]
89
+ if !item.nil?
90
+ # check if the item has been registered as a single instance item.
91
+ if item.single_instance == true
92
+ # check if the instance needs to be created
93
+ item.instance = create_instance(item) if item.instance.nil?
94
+
95
+ return item.instance
96
+ else
97
+ return create_instance(item)
98
+ end
99
+ else
100
+ # no dependency has been registered for the specified key,
101
+ # attempt to convert the key into a class name and initialize it.
102
+ class_name = "#{key}".split('_').collect(&:capitalize).join
103
+ puts "[#{self.class}] - WARNING: No registered dependency could be found for key: #{key}. " \
104
+ "Attempting to load class: #{class_name}."
105
+ Object.const_get(class_name).new
106
+ end
107
+ end
108
+
109
+ def load_groups
110
+ Sinject::DependencyGroup.descendants.sort_by(&:name).each do |g|
111
+ group = g.new
112
+ if (group.respond_to?(:valid?) && group.valid?) || (group.respond_to?(:is_valid?) && group.is_valid?)
113
+ group.register(self)
114
+ end
115
+ end
116
+ end
117
+
118
+ private
119
+
120
+ def validate_contract(dependency_class, contract_class)
121
+ # get the methods defined for the contract
122
+ contract_methods = (contract_class.instance_methods - Object.instance_methods)
123
+ # get the methods defined for the dependency
124
+ dependency_methods = (dependency_class.instance_methods - Object.instance_methods)
125
+ # calculate any methods specified in the contract that are not specified in the dependency
126
+ missing_methods = contract_methods - dependency_methods
127
+
128
+ if !missing_methods.empty?
129
+ raise Sinject::DependencyContractMissingMethodsException.new(missing_methods)
130
+ end
131
+
132
+ # loop through each contract method
133
+ contract_methods.each do |method|
134
+ # get the contract method parameters
135
+ contract_params = contract_class.instance_method(method).parameters.map{ |p| { type: p[0], name: p[1] } }
136
+
137
+ # get the dependency method parameters
138
+ dependency_params = dependency_class.instance_method(method).parameters.map{ |p| { type: p[0], name: p[1] } }
139
+
140
+ errors = []
141
+
142
+ contract_params.each do |cp|
143
+ dp = dependency_params.detect { |p| p[:name] == cp[:name] }
144
+ if dp.nil? || !match?(cp, dp)
145
+ errors << cp[:name]
146
+ end
147
+ end
148
+
149
+ dependency_params.each do |dp|
150
+ cp = contract_params.detect { |p| p[:name] == dp[:name] }
151
+ if cp.nil?
152
+ errors << dp[:name]
153
+ end
154
+ end
155
+
156
+ # check if any parameter errors
157
+ if errors.length > 0
158
+ raise Sinject::DependencyContractInvalidParametersException.new(method, errors)
159
+ end
160
+ end
161
+ end
162
+
163
+ def match?(contract, dependency)
164
+ return true if contract[:type] == dependency[:type]
165
+ return true if contract[:type] == :req && dependency[:type] == :opt
166
+ return true if contract[:type] == :keyreq && dependency[:type] == :key
167
+ return false
168
+ end
169
+
170
+ # this method is called to get a standard param type for comparison purposes
171
+ def param_type(type)
172
+ return :arg if type == :opt || type == :req
173
+ return :key if type == :keyreq || type == :key
174
+ end
175
+
176
+ def create_instance(item)
177
+ # check if a custom initializer block has been specified
178
+ if item.initialize_block != nil
179
+ # call the block to create the dependency instance
180
+ instance = item.initialize_block.call
181
+
182
+ # verify the block created the expected dependency type
183
+ raise Sinject::DependencyInitializeException.new(item.class_name) unless instance.is_a?(item.class_name)
184
+ else
185
+ instance = item.class_name.new
186
+ end
187
+
188
+ instance
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,9 @@
1
+ module Sinject
2
+ class ContainerItem
3
+ attr_accessor :key
4
+ attr_accessor :instance
5
+ attr_accessor :single_instance
6
+ attr_accessor :class_name
7
+ attr_accessor :initialize_block
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module Sinject
2
+ class DependencyGroup
3
+ def register(container)
4
+ end
5
+
6
+ def self.descendants
7
+ ObjectSpace.each_object(Class).select { |klass| klass < self }
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,64 @@
1
+ module Sinject
2
+ class DependencyContractMissingMethodsException < StandardError
3
+ def initialize(methods)
4
+ @methods = methods
5
+ end
6
+
7
+ def to_s
8
+ method_names = @methods.join(', ')
9
+ "The following methods have not been implemented: '#{method_names}'"
10
+ end
11
+ end
12
+
13
+ class DependencyContractInvalidParametersException < StandardError
14
+ def initialize(method, parameters)
15
+ @method = method
16
+ @parameters = parameters
17
+ end
18
+
19
+ def to_s
20
+ parameter_names = @parameters.join(', ')
21
+ "The method signature of method: '#{@method}' does not match the contract parameters: '#{parameter_names}'"
22
+ end
23
+ end
24
+
25
+ class DependencyInitializeException < StandardError
26
+
27
+ def initialize(expected_type)
28
+ @expected_type = expected_type
29
+ end
30
+
31
+ def to_s
32
+ "The custom dependency initializer does not return an object of the expected type: '#{@expected_type}'"
33
+ end
34
+
35
+ end
36
+
37
+ class DependencyRegistrationException < StandardError
38
+
39
+ def initialize(key)
40
+ @key = key
41
+ end
42
+
43
+ def to_s
44
+ "A Dependency has already been registered for the key: '#{@key}'"
45
+ end
46
+
47
+ end
48
+
49
+ class DependencyRegistrationKeyNotSpecifiedException < StandardError
50
+
51
+ def to_s
52
+ "A key must be specified to register a dependency."
53
+ end
54
+
55
+ end
56
+
57
+ class DependencyRegistrationClassNotSpecifiedException < StandardError
58
+
59
+ def to_s
60
+ "A dependency class must be specified to register a dependency."
61
+ end
62
+
63
+ end
64
+ end
@@ -1,3 +1,5 @@
1
+ # Namespace
1
2
  module Sinject
2
- VERSION = "0.2.4"
3
+ # :nodoc:
4
+ VERSION = '1.1.1'.freeze
3
5
  end
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinject
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
- - vaughan britton
7
+ - Sage One
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-03-03 00:00:00.000000000 Z
11
+ date: 2021-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.11'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.11'
27
27
  - !ruby/object:Gem::Dependency
@@ -52,26 +52,37 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.21.2
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.21.2
55
69
  description: A simple dependency injection framework.
56
70
  email:
57
- - vaughanbritton@gmail.com
71
+ - vaughan.britton@sage.com
58
72
  executables: []
59
73
  extensions: []
60
74
  extra_rdoc_files: []
61
75
  files:
62
- - ".gitignore"
63
- - ".rspec"
64
- - CODE_OF_CONDUCT.md
65
- - Gemfile
66
- - LICENSE.txt
67
- - README.md
68
- - Rakefile
69
76
  - bin/console
70
77
  - bin/setup
71
78
  - lib/sinject.rb
79
+ - lib/sinject/class.rb
80
+ - lib/sinject/container.rb
81
+ - lib/sinject/container_item.rb
82
+ - lib/sinject/dependency_group.rb
83
+ - lib/sinject/exceptions.rb
72
84
  - lib/sinject/version.rb
73
- - sinject.gemspec
74
- homepage: https://github.com/vaughanbrittonsage/sinject
85
+ homepage: https://github.com/sage/sinject
75
86
  licenses:
76
87
  - MIT
77
88
  metadata: {}
@@ -90,10 +101,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
101
  - !ruby/object:Gem::Version
91
102
  version: '0'
92
103
  requirements: []
93
- rubyforge_project:
94
- rubygems_version: 2.5.1
104
+ rubygems_version: 3.0.8
95
105
  signing_key:
96
106
  specification_version: 4
97
107
  summary: Simple Dependency Injection.
98
108
  test_files: []
99
- has_rdoc:
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --color
2
- --require spec_helper
data/CODE_OF_CONDUCT.md DELETED
@@ -1,49 +0,0 @@
1
- # Contributor Code of Conduct
2
-
3
- As contributors and maintainers of this project, and in the interest of
4
- fostering an open and welcoming community, we pledge to respect all people who
5
- contribute through reporting issues, posting feature requests, updating
6
- documentation, submitting pull requests or patches, and other activities.
7
-
8
- We are committed to making participation in this project a harassment-free
9
- experience for everyone, regardless of level of experience, gender, gender
10
- identity and expression, sexual orientation, disability, personal appearance,
11
- body size, race, ethnicity, age, religion, or nationality.
12
-
13
- Examples of unacceptable behavior by participants include:
14
-
15
- * The use of sexualized language or imagery
16
- * Personal attacks
17
- * Trolling or insulting/derogatory comments
18
- * Public or private harassment
19
- * Publishing other's private information, such as physical or electronic
20
- addresses, without explicit permission
21
- * Other unethical or unprofessional conduct
22
-
23
- Project maintainers have the right and responsibility to remove, edit, or
24
- reject comments, commits, code, wiki edits, issues, and other contributions
25
- that are not aligned to this Code of Conduct, or to ban temporarily or
26
- permanently any contributor for other behaviors that they deem inappropriate,
27
- threatening, offensive, or harmful.
28
-
29
- By adopting this Code of Conduct, project maintainers commit themselves to
30
- fairly and consistently applying these principles to every aspect of managing
31
- this project. Project maintainers who do not follow or enforce the Code of
32
- Conduct may be permanently removed from the project team.
33
-
34
- This code of conduct applies both within project spaces and in public spaces
35
- when an individual is representing the project or its community.
36
-
37
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
- reported by contacting a project maintainer at vaughan.britton@sage.com. All
39
- complaints will be reviewed and investigated and will result in a response that
40
- is deemed necessary and appropriate to the circumstances. Maintainers are
41
- obligated to maintain confidentiality with regard to the reporter of an
42
- incident.
43
-
44
- This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
- version 1.3.0, available at
46
- [http://contributor-covenant.org/version/1/3/0/][version]
47
-
48
- [homepage]: http://contributor-covenant.org
49
- [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile DELETED
@@ -1,3 +0,0 @@
1
- source "https://rubygems.org"
2
- gemspec
3
-
data/LICENSE.txt DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2016 vaughanbrittonsage
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
data/README.md DELETED
@@ -1,139 +0,0 @@
1
-
2
- # Sinject
3
-
4
- Welcome to Sinject! a simple dependency injection framework for ruby.
5
-
6
- ## Installation
7
-
8
- Add this line to your application's Gemfile:
9
-
10
- ```ruby
11
- gem 'sinject'
12
- ```
13
-
14
- And then execute:
15
-
16
- $ bundle
17
-
18
- Or install it yourself as:
19
-
20
- $ gem install sinject
21
-
22
- ## Usage
23
-
24
- **Rails Setup**
25
-
26
- If you're using rails then after you've installed the gem you need to create a *'dependencies.rb'* file within the *'/config/initializers'* directory of the rails application.
27
-
28
- **Registering dependencies**
29
-
30
- Dependency objects need to be registered with the container before use, to do so you need to configure the SinjectContainer: [If you're using rails this will need to be done within the *'dependencies.rb'* file]
31
-
32
- #initialize the container
33
- container = SinjectContainer.new
34
-
35
- #register your dependencies
36
- container.register(:cache_store, RedisCacheStore, true)
37
- container.register(:country_repository, MySqlCountryRepository, false)
38
-
39
- Dependencies can be registered with the container in 2 modes:
40
-
41
- - **Single instance:** This mode ensures that only 1 instance is created for the registered dependency and that all requests to the container for that dependency return the same instance.
42
- - **Multi instance:** This mode ensures that a new instance of the registered dependency is returned for each request received by the container.
43
-
44
- The registration mode can be set by specifying **true** or **false** to the *'single_instance'* argument of the containers register method.
45
-
46
- Dependencies that require custom initialization can be registered with an initialization block to handle the creation of the dependency, this allows you more control over how the dependency is created if required:
47
-
48
- container.register(:cache_store, RedisCacheStore, true) do
49
- instance = RedisCacheStore.new
50
- instance.host = 'http://localhost'
51
- instance.port = '6369'
52
- instance
53
- end
54
-
55
- Dependencies with a custom initialization block must return an object of the registered dependency class type, if an unexpected instance is returned then Sinject will raise a `DependencyInitializeException`.
56
-
57
- **Assigning dependencies**
58
-
59
- To assign a dependency to an object you need to add the dependency attribute to the class and specify the symbol key that was used to register the dependency with the SinjectContainer:
60
-
61
- class MySqlCountryRepository
62
-
63
- dependency :cache_store
64
-
65
- .....
66
- end
67
-
68
- class CountryController < ActionController::Base
69
-
70
- dependency :country_repository
71
-
72
- .....
73
- end
74
-
75
- Sinject will then inject the registered dependency to that object and it will be accessible via the dependency key:
76
-
77
- country_controller.country_repository.cache_store
78
-
79
-
80
- **Dependency Contracts**
81
-
82
- Dependency contracts can be defined to validate registered dependencies are valid for the task they are being registered for. *(If you are familiar with other type based languages then you can think of this as a kind of Interface)*
83
-
84
- To create a dependency contract you need to create a new class with empty methods for each of the methods that the dependency needs to respond to in order to fulfill it's role:
85
-
86
- class LoggerContract
87
- def write(message)
88
- end
89
- end
90
-
91
- Then when registering a dependency for the role the contract is written for, you can assign the contract:
92
-
93
- #register the dependency
94
- container.register(:logger, FileLogger, false, LoggerContract)
95
-
96
- Sinject will then validate that the registered dependency meets the requirements specified within the contract. If a dependency does not meet the contract requirements then 1 of the following exceptions will be raised:
97
-
98
- - `DependencyContractMissingMethodsException` is raised when 1 or more methods from the contract could not be found on the dependency.
99
- - `DependencyContractInvalidParametersException` is raised when the parameters of a contract method do not match the parameters found on a dependency method.
100
-
101
- **Dependency Groups**
102
-
103
- Dependency registration groups can be created to allow groups of dependencies to be set without the need for manual registration *(e.g. to include with a gem for auto registration)*, or to allow different dependency groups to be loaded in different circumstances *(e.g. per environment)*.
104
-
105
- To create a dependency group, create a class that inherits from the `DependencyGroup` base class and implement the `register` & `is_valid?` methods.
106
-
107
- For example:
108
-
109
- #create a development only dependency group
110
- class DevelopmentDependencies < DependencyGroup
111
- def register(container)
112
- container.register(:cache_store, LocalCacheStore, true)
113
- container.register(:logger, TerminalLogger, true)
114
- end
115
-
116
- def is_valid?
117
- Rails.env.development?
118
- end
119
- end
120
-
121
- To load valid dependency groups the following method needs to be called from the container:
122
-
123
- container.load_groups
124
-
125
-
126
- ## Development
127
-
128
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
129
-
130
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
131
-
132
- ## Contributing
133
-
134
- Bug reports and pull requests are welcome on GitHub at https://github.com/vaughanbrittonsage/sinject. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
135
-
136
-
137
- ## License
138
-
139
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile DELETED
@@ -1,2 +0,0 @@
1
- require "bundler/gem_tasks"
2
- task :default => :spec
data/sinject.gemspec DELETED
@@ -1,25 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'sinject/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "sinject"
8
- spec.version = Sinject::VERSION
9
- spec.authors = ["vaughan britton"]
10
- spec.email = ["vaughanbritton@gmail.com"]
11
-
12
- spec.summary = "Simple Dependency Injection."
13
- spec.description = "A simple dependency injection framework."
14
- spec.homepage = "https://github.com/vaughanbrittonsage/sinject"
15
- spec.license = "MIT"
16
-
17
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
- spec.bindir = "exe"
19
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
- spec.require_paths = ["lib"]
21
-
22
- spec.add_development_dependency "bundler", "~> 1.11"
23
- spec.add_development_dependency "rake", "~> 10.0"
24
- spec.add_development_dependency "rspec", "~> 3.0"
25
- end