pinball 0.0.2 → 0.0.3
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 +4 -4
- data/README.md +127 -0
- data/lib/pinball/class.rb +1 -0
- data/lib/pinball/container.rb +1 -1
- data/lib/pinball/version.rb +1 -1
- data/lib/pinball.rb +14 -4
- data/spec/lib/pinball/class_spec.rb +21 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0a151b6a0ce9ddb00755568ae644cb809e6f13a
|
4
|
+
data.tar.gz: b842f2c2e9acacd61444d82fa411a03bd6769e47
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 828227b6d3b7847301a7958d325e377ca2833c7f1e7eb55af04dfe16b1eed7d3c4615511fa74ca2bebfbb9e9b8792298828da307c481f30e45cbd402f98a095f
|
7
|
+
data.tar.gz: b2d9c11f9848feb81f5ccf1b22933e84a5a413abb8fc2133854c6a46c8f362bb31da6afb544c95500181b19127efba41662ba915cd639d9d71acfe2c2321d52d
|
data/README.md
CHANGED
@@ -0,0 +1,127 @@
|
|
1
|
+
## Pinball [](https://travis-ci.org/zhulik/pinball) [](https://coveralls.io/r/zhulik/pinball?branch=master) [](https://codeclimate.com/github/zhulik/pinball)
|
2
|
+
|
3
|
+
### Simple IOC Container and DI tool for ruby.
|
4
|
+
|
5
|
+
Pinball is a library for using dependency injection within Ruby
|
6
|
+
applications. It provides a clear IOC Container that manages
|
7
|
+
dependencies between your classes.
|
8
|
+
|
9
|
+
# Features
|
10
|
+
|
11
|
+
* Stores objects, classes(as factories) and blocks
|
12
|
+
* Can inject dependencies to classes and instances
|
13
|
+
* Simple DSL for configuring the container
|
14
|
+
* Stored block will be call in dependent class instance
|
15
|
+
* You can describe any context-dependent code in blocks
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
### Class injection
|
20
|
+
|
21
|
+
Consider a `Service` class that has a dependency on a `Repository`. We would
|
22
|
+
like this dependency to be available to the service when it is created.
|
23
|
+
|
24
|
+
First we create a container object and declare the dependencies.
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
require 'pinball'
|
28
|
+
|
29
|
+
Pinball::Container.configure do
|
30
|
+
define :repository, Repository
|
31
|
+
end
|
32
|
+
```
|
33
|
+
|
34
|
+
Then we declare the `repository` dependency in the Service class by
|
35
|
+
using the `inject` declaration.
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
class Service
|
39
|
+
inject :repository
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
Now we can instantiate Service object and `repository` method will
|
44
|
+
be already accessible in it's constructor! In this case *repository*
|
45
|
+
method will return the instance of Repository.
|
46
|
+
**Notice:** each call of `repository` will create new instance of `Repository`.
|
47
|
+
|
48
|
+
### Object injection
|
49
|
+
|
50
|
+
Also you can inject any already existed object
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
require 'pinball'
|
54
|
+
|
55
|
+
Pinball::Container.configure do
|
56
|
+
define :string, 'any pre-defined string'
|
57
|
+
end
|
58
|
+
```
|
59
|
+
|
60
|
+
In this case `string` method will return 'any pre-defined string'
|
61
|
+
|
62
|
+
### Block injection
|
63
|
+
|
64
|
+
The most powerful feature of pinball is block injection.
|
65
|
+
For example, you have `FirstService` class, that dependent on
|
66
|
+
`SecondService` class, but for instantiating `SecondService` you need
|
67
|
+
to pass `@current_user` from `FirstService` to it's constructor:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
class FirstService
|
71
|
+
inject :second_service
|
72
|
+
|
73
|
+
def initialize(current_user)
|
74
|
+
@current_user = current_user
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class SecondService
|
79
|
+
def initialize(current_user)
|
80
|
+
@current_user = current_user
|
81
|
+
end
|
82
|
+
end
|
83
|
+
```
|
84
|
+
|
85
|
+
Simple defining of `SecondService` dependency will not work here.
|
86
|
+
So we can define dependency with a block:
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
Pinball::Container.configure do
|
90
|
+
define :second_service do
|
91
|
+
SecondService.new(@current_user)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
```
|
95
|
+
|
96
|
+
This block will be executed it `FirstService` instance context where
|
97
|
+
`@current_user` will be accessible.
|
98
|
+
**Notice:** each call of `second_service` will call this block over and over again.
|
99
|
+
|
100
|
+
### class_inject
|
101
|
+
|
102
|
+
Sometimes you need to inject dependency to class, when it must be available in
|
103
|
+
class methods. For this purpose Pinball has `class_inject` declaration:
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
class Foo
|
107
|
+
class_inject :baz
|
108
|
+
end
|
109
|
+
|
110
|
+
Foo.baz
|
111
|
+
```
|
112
|
+
|
113
|
+
## Future plans
|
114
|
+
|
115
|
+
* Rails integration
|
116
|
+
* Dependency lifecycle managing in Rails context
|
117
|
+
* Smart caching
|
118
|
+
|
119
|
+
## Contributing
|
120
|
+
|
121
|
+
1. Fork it
|
122
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
123
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
124
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
125
|
+
5. Create new Pull Request
|
126
|
+
|
127
|
+
Inspired by [Encase gem](https://github.com/dsawardekar/encase "Encase gem")
|
data/lib/pinball/class.rb
CHANGED
data/lib/pinball/container.rb
CHANGED
@@ -44,7 +44,7 @@ module Pinball
|
|
44
44
|
def inject(target)
|
45
45
|
target.class.dependencies.each do |dep|
|
46
46
|
target.define_singleton_method dep do
|
47
|
-
Container.instance.items[dep].fetch(self)
|
47
|
+
Container.instance.items.merge(overridden_dependencies)[dep].fetch(self)
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
data/lib/pinball/version.rb
CHANGED
data/lib/pinball.rb
CHANGED
@@ -3,14 +3,24 @@ require 'pinball/container'
|
|
3
3
|
require 'pinball/class'
|
4
4
|
|
5
5
|
module Pinball
|
6
|
+
module Methods
|
7
|
+
attr_reader :overridden_dependencies
|
8
|
+
|
9
|
+
def override_dependency(key, value = nil, &block)
|
10
|
+
@overridden_dependencies[key] = ContainerItem.new(value || block)
|
11
|
+
Container.instance.inject(self)
|
12
|
+
self
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :dependencies
|
17
|
+
|
18
|
+
|
6
19
|
def new(*args)
|
7
20
|
object = allocate
|
8
21
|
Container.instance.inject(object)
|
9
22
|
object.send(:initialize, *args)
|
23
|
+
object.instance_variable_set(:@overridden_dependencies, {})
|
10
24
|
object
|
11
25
|
end
|
12
|
-
|
13
|
-
def dependencies
|
14
|
-
@dependencies
|
15
|
-
end
|
16
26
|
end
|
@@ -45,4 +45,25 @@ describe Class do
|
|
45
45
|
expect(foo.baz).to eq(0)
|
46
46
|
end
|
47
47
|
end
|
48
|
+
|
49
|
+
describe '#override_dependency' do
|
50
|
+
let!(:foo_instance) { foo.inject :baz ; foo.new }
|
51
|
+
|
52
|
+
subject { foo_instance.override_dependency(:baz, 1) }
|
53
|
+
|
54
|
+
it 'adds overridden dependency' do
|
55
|
+
subject
|
56
|
+
expect(foo_instance.overridden_dependencies[:baz]).not_to be_nil
|
57
|
+
#expect(foo_instance.baz).to eq(1)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'resolves overridden dependency' do
|
61
|
+
subject
|
62
|
+
expect(foo_instance.baz).to eq(1)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'returns self' do
|
66
|
+
expect(subject).to eq(foo_instance)
|
67
|
+
end
|
68
|
+
end
|
48
69
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pinball
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gleb Sinyavsky
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|