senro_usecaser 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 +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +72 -0
- data/LICENSE +21 -0
- data/README.md +1069 -0
- data/Rakefile +12 -0
- data/Steepfile +24 -0
- data/examples/RBS_GENERATION.md +16 -0
- data/examples/namespace_demo.rb +751 -0
- data/examples/order_system.rb +1279 -0
- data/examples/sig/namespace_demo.rbs +279 -0
- data/examples/sig/order_system.rbs +685 -0
- data/lefthook.yml +31 -0
- data/lib/senro_usecaser/base.rb +660 -0
- data/lib/senro_usecaser/configuration.rb +149 -0
- data/lib/senro_usecaser/container.rb +315 -0
- data/lib/senro_usecaser/error.rb +88 -0
- data/lib/senro_usecaser/provider.rb +212 -0
- data/lib/senro_usecaser/result.rb +182 -0
- data/lib/senro_usecaser/version.rb +8 -0
- data/lib/senro_usecaser.rb +155 -0
- data/sig/generated/senro_usecaser/base.rbs +365 -0
- data/sig/generated/senro_usecaser/configuration.rbs +80 -0
- data/sig/generated/senro_usecaser/container.rbs +190 -0
- data/sig/generated/senro_usecaser/error.rbs +58 -0
- data/sig/generated/senro_usecaser/provider.rbs +153 -0
- data/sig/generated/senro_usecaser/result.rbs +109 -0
- data/sig/generated/senro_usecaser/version.rbs +6 -0
- data/sig/generated/senro_usecaser.rbs +113 -0
- data/sig/overrides.rbs +16 -0
- metadata +77 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module SenroUsecaser
|
|
6
|
+
# Base class for dependency providers
|
|
7
|
+
#
|
|
8
|
+
# Providers allow organizing dependency registrations across multiple files.
|
|
9
|
+
# Each provider is responsible for registering a group of related dependencies.
|
|
10
|
+
#
|
|
11
|
+
# @example Basic provider
|
|
12
|
+
# class UserProvider < SenroUsecaser::Provider
|
|
13
|
+
# def register(container)
|
|
14
|
+
# container.register(:user_repository, UserRepository.new)
|
|
15
|
+
# container.register_singleton(:user_service) do |c|
|
|
16
|
+
# UserService.new(repo: c.resolve(:user_repository))
|
|
17
|
+
# end
|
|
18
|
+
# end
|
|
19
|
+
# end
|
|
20
|
+
#
|
|
21
|
+
# @example Provider with namespace
|
|
22
|
+
# class AdminProvider < SenroUsecaser::Provider
|
|
23
|
+
# namespace :admin
|
|
24
|
+
#
|
|
25
|
+
# def register(container)
|
|
26
|
+
# container.register(:user_repository, AdminUserRepository.new)
|
|
27
|
+
# end
|
|
28
|
+
# end
|
|
29
|
+
#
|
|
30
|
+
# @example Provider with dependencies
|
|
31
|
+
# class PersistenceProvider < SenroUsecaser::Provider
|
|
32
|
+
# depends_on CoreProvider
|
|
33
|
+
#
|
|
34
|
+
# def register(container)
|
|
35
|
+
# container.register(:database, Database.connect)
|
|
36
|
+
# end
|
|
37
|
+
# end
|
|
38
|
+
#
|
|
39
|
+
# @example Conditional provider
|
|
40
|
+
# class DevelopmentProvider < SenroUsecaser::Provider
|
|
41
|
+
# enabled_if { SenroUsecaser.env.development? }
|
|
42
|
+
# end
|
|
43
|
+
#
|
|
44
|
+
class Provider
|
|
45
|
+
class << self
|
|
46
|
+
# Declares dependencies on other providers
|
|
47
|
+
#
|
|
48
|
+
# @example
|
|
49
|
+
# class PersistenceProvider < SenroUsecaser::Provider
|
|
50
|
+
# depends_on CoreProvider
|
|
51
|
+
# depends_on ConfigProvider
|
|
52
|
+
# end
|
|
53
|
+
#
|
|
54
|
+
#: (*singleton(Provider)) -> void
|
|
55
|
+
def depends_on(*provider_classes)
|
|
56
|
+
provider_classes.each do |klass|
|
|
57
|
+
provider_dependencies << klass unless provider_dependencies.include?(klass)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Returns the list of provider dependencies
|
|
62
|
+
#
|
|
63
|
+
#: () -> Array[singleton(Provider)]
|
|
64
|
+
def provider_dependencies
|
|
65
|
+
@provider_dependencies ||= [] #: Array[singleton(Provider)]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Sets a condition for enabling this provider
|
|
69
|
+
#
|
|
70
|
+
# @example
|
|
71
|
+
# class DevelopmentProvider < SenroUsecaser::Provider
|
|
72
|
+
# enabled_if { Rails.env.development? }
|
|
73
|
+
# end
|
|
74
|
+
#
|
|
75
|
+
#: () { () -> bool } -> void
|
|
76
|
+
def enabled_if(&block)
|
|
77
|
+
@enabled_condition = block
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Returns whether this provider is enabled
|
|
81
|
+
#
|
|
82
|
+
#: () -> bool
|
|
83
|
+
def enabled?
|
|
84
|
+
return true unless @enabled_condition
|
|
85
|
+
|
|
86
|
+
@enabled_condition.call
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Sets the namespace for this provider's registrations
|
|
90
|
+
#
|
|
91
|
+
# @example
|
|
92
|
+
# class AdminProvider < SenroUsecaser::Provider
|
|
93
|
+
# namespace :admin
|
|
94
|
+
# end
|
|
95
|
+
#
|
|
96
|
+
#: ((Symbol | String)) -> void
|
|
97
|
+
def namespace(name = nil)
|
|
98
|
+
if name
|
|
99
|
+
@provider_namespace = name
|
|
100
|
+
else
|
|
101
|
+
@provider_namespace
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# @rbs!
|
|
106
|
+
# def self.provider_namespace: () -> (Symbol | String)?
|
|
107
|
+
attr_reader :provider_namespace
|
|
108
|
+
|
|
109
|
+
# Registers this provider's dependencies to the given container
|
|
110
|
+
#
|
|
111
|
+
#: (Container) -> void
|
|
112
|
+
def call(container)
|
|
113
|
+
new.register_to(container)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Registers dependencies to the container, wrapped in namespace if declared
|
|
118
|
+
#
|
|
119
|
+
#: (Container) -> void
|
|
120
|
+
def register_to(container)
|
|
121
|
+
before_register(container)
|
|
122
|
+
|
|
123
|
+
ns = effective_namespace
|
|
124
|
+
if ns
|
|
125
|
+
# Capture self to call provider's register method within namespace context
|
|
126
|
+
provider = self
|
|
127
|
+
container.namespace(ns) { provider.register(container) }
|
|
128
|
+
else
|
|
129
|
+
register(container)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Returns the effective namespace for this provider
|
|
134
|
+
# Uses explicitly declared namespace, or infers from module structure if configured
|
|
135
|
+
#
|
|
136
|
+
#: () -> (Symbol | String)?
|
|
137
|
+
def effective_namespace
|
|
138
|
+
# Explicit namespace takes precedence
|
|
139
|
+
return self.class.provider_namespace if self.class.provider_namespace
|
|
140
|
+
|
|
141
|
+
# Infer from module structure if enabled
|
|
142
|
+
return nil unless SenroUsecaser.configuration.infer_namespace_from_module
|
|
143
|
+
|
|
144
|
+
infer_namespace_from_class
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Infers namespace from the class's module structure
|
|
148
|
+
#
|
|
149
|
+
# @example
|
|
150
|
+
# Admin::UserProvider => "admin"
|
|
151
|
+
# Admin::Reports::ReportProvider => "admin::reports"
|
|
152
|
+
# CoreProvider => nil
|
|
153
|
+
#
|
|
154
|
+
#: () -> String?
|
|
155
|
+
def infer_namespace_from_class
|
|
156
|
+
class_name = self.class.name
|
|
157
|
+
return nil unless class_name
|
|
158
|
+
|
|
159
|
+
parts = class_name.split("::")
|
|
160
|
+
return nil if parts.length <= 1
|
|
161
|
+
|
|
162
|
+
# Remove the class name itself, keep only module parts
|
|
163
|
+
module_parts = parts[0...-1] || [] #: Array[String]
|
|
164
|
+
return nil if module_parts.empty?
|
|
165
|
+
|
|
166
|
+
# Convert to lowercase namespace format (Admin::Reports => "admin::reports")
|
|
167
|
+
module_parts.map { |part| part.gsub(/([a-z])([A-Z])/, '\1_\2').downcase }.join("::")
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Called before register. Override in subclasses.
|
|
171
|
+
#
|
|
172
|
+
# @example
|
|
173
|
+
# def before_register(container)
|
|
174
|
+
# # Setup work
|
|
175
|
+
# end
|
|
176
|
+
#
|
|
177
|
+
#: (Container) -> void
|
|
178
|
+
def before_register(container); end
|
|
179
|
+
|
|
180
|
+
# Override this method to register dependencies
|
|
181
|
+
#
|
|
182
|
+
# @example
|
|
183
|
+
# def register(container)
|
|
184
|
+
# container.register(:logger, Logger.new)
|
|
185
|
+
# end
|
|
186
|
+
#
|
|
187
|
+
#: (Container) -> void
|
|
188
|
+
def register(container)
|
|
189
|
+
raise NotImplementedError, "#{self.class.name}#register must be implemented"
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
# Called after all providers are registered. Override in subclasses.
|
|
193
|
+
#
|
|
194
|
+
# @example
|
|
195
|
+
# def after_boot(container)
|
|
196
|
+
# container.resolve(:database).verify_connection!
|
|
197
|
+
# end
|
|
198
|
+
#
|
|
199
|
+
#: (Container) -> void
|
|
200
|
+
def after_boot(container); end
|
|
201
|
+
|
|
202
|
+
# Called on application shutdown. Override in subclasses.
|
|
203
|
+
#
|
|
204
|
+
# @example
|
|
205
|
+
# def shutdown(container)
|
|
206
|
+
# container.resolve(:database).disconnect
|
|
207
|
+
# end
|
|
208
|
+
#
|
|
209
|
+
#: (Container) -> void
|
|
210
|
+
def shutdown(container); end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module SenroUsecaser
|
|
6
|
+
# Represents the result of a UseCase execution
|
|
7
|
+
#
|
|
8
|
+
# Result is a generic type that holds either a success value or an array of errors.
|
|
9
|
+
# Use {.success} and {.failure} class methods to create instances.
|
|
10
|
+
#
|
|
11
|
+
# @example Success case
|
|
12
|
+
# result = SenroUsecaser::Result.success(user)
|
|
13
|
+
# result.success? # => true
|
|
14
|
+
# result.value # => user
|
|
15
|
+
#
|
|
16
|
+
# @example Failure case
|
|
17
|
+
# result = SenroUsecaser::Result.failure(
|
|
18
|
+
# SenroUsecaser::Error.new(code: :not_found, message: "User not found")
|
|
19
|
+
# )
|
|
20
|
+
# result.failure? # => true
|
|
21
|
+
# result.errors # => [#<SenroUsecaser::Error ...>]
|
|
22
|
+
#
|
|
23
|
+
# @rbs generic T
|
|
24
|
+
class Result
|
|
25
|
+
# @rbs!
|
|
26
|
+
# attr_reader value: T?
|
|
27
|
+
# attr_reader errors: Array[Error]
|
|
28
|
+
|
|
29
|
+
# @rbs skip
|
|
30
|
+
attr_reader :value
|
|
31
|
+
# @rbs skip
|
|
32
|
+
attr_reader :errors
|
|
33
|
+
|
|
34
|
+
# Creates a success Result with the given value
|
|
35
|
+
#
|
|
36
|
+
#: [T] (T) -> Result[T]
|
|
37
|
+
def self.success(value)
|
|
38
|
+
new(value: value, errors: [])
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Creates a failure Result with the given errors
|
|
42
|
+
#
|
|
43
|
+
#: (*Error) -> Result[untyped]
|
|
44
|
+
def self.failure(*errors)
|
|
45
|
+
errors = errors.flatten
|
|
46
|
+
raise ArgumentError, "At least one error is required for failure" if errors.empty?
|
|
47
|
+
|
|
48
|
+
new(value: nil, errors: errors)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Creates a failure Result from an exception
|
|
52
|
+
#
|
|
53
|
+
# @example
|
|
54
|
+
# begin
|
|
55
|
+
# # some code that raises
|
|
56
|
+
# rescue => e
|
|
57
|
+
# Result.from_exception(e)
|
|
58
|
+
# end
|
|
59
|
+
#
|
|
60
|
+
#: (Exception, ?code: Symbol) -> Result[untyped]
|
|
61
|
+
def self.from_exception(exception, code: :exception)
|
|
62
|
+
error = Error.from_exception(exception, code: code)
|
|
63
|
+
failure(error)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Executes a block and captures any exception as a failure Result
|
|
67
|
+
#
|
|
68
|
+
# @example
|
|
69
|
+
# result = Result.capture { User.find(id) }
|
|
70
|
+
# # If User.find raises, result is a failure with the exception
|
|
71
|
+
# # If User.find succeeds, result is a success with the return value
|
|
72
|
+
#
|
|
73
|
+
# @example With specific exception classes
|
|
74
|
+
# result = Result.capture(ActiveRecord::RecordNotFound, code: :not_found) do
|
|
75
|
+
# User.find(id)
|
|
76
|
+
# end
|
|
77
|
+
#
|
|
78
|
+
#: [T] (*Class, ?code: Symbol) { () -> T } -> Result[T]
|
|
79
|
+
def self.capture(*exception_classes, code: :exception, &block)
|
|
80
|
+
raise ArgumentError, "Block is required" unless block
|
|
81
|
+
|
|
82
|
+
exception_classes = [StandardError] if exception_classes.empty?
|
|
83
|
+
value = block.call
|
|
84
|
+
success(value)
|
|
85
|
+
rescue *exception_classes => e
|
|
86
|
+
from_exception(e, code: code)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
#: (?value: T?, ?errors: Array[Error]) -> void
|
|
90
|
+
def initialize(value: nil, errors: [])
|
|
91
|
+
@value = value
|
|
92
|
+
@errors = errors.freeze
|
|
93
|
+
freeze
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Returns true if the result is a success
|
|
97
|
+
#
|
|
98
|
+
#: () -> bool
|
|
99
|
+
def success?
|
|
100
|
+
errors.empty?
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Returns true if the result is a failure
|
|
104
|
+
#
|
|
105
|
+
#: () -> bool
|
|
106
|
+
def failure?
|
|
107
|
+
!success?
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Returns the value if success, otherwise raises an error
|
|
111
|
+
#
|
|
112
|
+
#: () -> T
|
|
113
|
+
def value! # steep:ignore MethodBodyTypeMismatch
|
|
114
|
+
raise "Cannot unwrap value from a failure result" if failure?
|
|
115
|
+
|
|
116
|
+
@value
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Returns the value if success, otherwise returns the given default
|
|
120
|
+
#
|
|
121
|
+
#: [U] (U) -> (T | U)
|
|
122
|
+
def value_or(default) # steep:ignore MethodBodyTypeMismatch
|
|
123
|
+
if success?
|
|
124
|
+
@value
|
|
125
|
+
else
|
|
126
|
+
default
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Applies a block to the value if success, returns failure with same errors if failure
|
|
131
|
+
#
|
|
132
|
+
#: [U] () { (T) -> U } -> Result[U]
|
|
133
|
+
def map(&block)
|
|
134
|
+
return Result.new(value: nil, errors: errors) if failure?
|
|
135
|
+
|
|
136
|
+
# @type var v: untyped
|
|
137
|
+
v = @value
|
|
138
|
+
Result.success(block.call(v))
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Applies a block to the value if success, returns failure with same errors if failure
|
|
142
|
+
# The block should return a Result
|
|
143
|
+
#
|
|
144
|
+
#: [U] () { (T) -> Result[U] } -> Result[U]
|
|
145
|
+
def and_then(&block)
|
|
146
|
+
return Result.new(value: nil, errors: errors) if failure?
|
|
147
|
+
|
|
148
|
+
# @type var v: untyped
|
|
149
|
+
v = @value
|
|
150
|
+
block.call(v)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Applies a block to the errors if failure, returns self if success
|
|
154
|
+
#
|
|
155
|
+
#: () { (Array[Error]) -> Result[T] } -> Result[T]
|
|
156
|
+
def or_else(&block)
|
|
157
|
+
return self if success?
|
|
158
|
+
|
|
159
|
+
block.call(errors)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
#: (Result[untyped]) -> bool
|
|
163
|
+
def ==(other)
|
|
164
|
+
return false unless other.is_a?(Result)
|
|
165
|
+
|
|
166
|
+
# @type var v: untyped
|
|
167
|
+
v = @value
|
|
168
|
+
v == other.value && errors == other.errors
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
#: () -> String
|
|
172
|
+
def inspect
|
|
173
|
+
if success?
|
|
174
|
+
# @type var v: untyped
|
|
175
|
+
v = @value
|
|
176
|
+
"#<#{self.class.name} success value=#{v.inspect}>"
|
|
177
|
+
else
|
|
178
|
+
"#<#{self.class.name} failure errors=#{errors.inspect}>"
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
require_relative "senro_usecaser/version"
|
|
6
|
+
require_relative "senro_usecaser/error"
|
|
7
|
+
require_relative "senro_usecaser/result"
|
|
8
|
+
require_relative "senro_usecaser/container"
|
|
9
|
+
require_relative "senro_usecaser/configuration"
|
|
10
|
+
require_relative "senro_usecaser/provider"
|
|
11
|
+
require_relative "senro_usecaser/base"
|
|
12
|
+
|
|
13
|
+
# SenroUsecaser is a type-safe UseCase pattern implementation library for Ruby.
|
|
14
|
+
#
|
|
15
|
+
# It provides:
|
|
16
|
+
# - Type-safe input/output with RBS Inline
|
|
17
|
+
# - DI container with namespaces
|
|
18
|
+
# - Flexible composition with organize/include/extend patterns
|
|
19
|
+
#
|
|
20
|
+
# @example Basic UseCase
|
|
21
|
+
# class CreateUserUseCase < SenroUsecaser::Base
|
|
22
|
+
# def call(name:, email:)
|
|
23
|
+
# user = User.create(name: name, email: email)
|
|
24
|
+
# success(user)
|
|
25
|
+
# end
|
|
26
|
+
# end
|
|
27
|
+
#
|
|
28
|
+
# result = CreateUserUseCase.call(name: "Taro", email: "taro@example.com")
|
|
29
|
+
# if result.success?
|
|
30
|
+
# puts result.value.name
|
|
31
|
+
# end
|
|
32
|
+
module SenroUsecaser
|
|
33
|
+
class << self
|
|
34
|
+
# Returns the global container instance
|
|
35
|
+
#
|
|
36
|
+
# @example
|
|
37
|
+
# SenroUsecaser.container.register(:logger, Logger.new)
|
|
38
|
+
#
|
|
39
|
+
#: () -> Container
|
|
40
|
+
def container
|
|
41
|
+
@container ||= Container.new
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Sets the global container instance
|
|
45
|
+
#
|
|
46
|
+
# @example
|
|
47
|
+
# SenroUsecaser.container = MyCustomContainer.new
|
|
48
|
+
#
|
|
49
|
+
#: (Container) -> Container
|
|
50
|
+
attr_writer :container
|
|
51
|
+
|
|
52
|
+
# Resets the global container (useful for testing)
|
|
53
|
+
#
|
|
54
|
+
#: () -> void
|
|
55
|
+
def reset_container!
|
|
56
|
+
@container = nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Registers a provider to the global container
|
|
60
|
+
#
|
|
61
|
+
# @example
|
|
62
|
+
# SenroUsecaser.register_provider(UserProvider)
|
|
63
|
+
#
|
|
64
|
+
#: (singleton(Provider)) -> void
|
|
65
|
+
def register_provider(provider_class)
|
|
66
|
+
provider_class.call(container)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Registers multiple providers to the global container
|
|
70
|
+
#
|
|
71
|
+
# @example
|
|
72
|
+
# SenroUsecaser.register_providers(UserProvider, OrderProvider, PaymentProvider)
|
|
73
|
+
#
|
|
74
|
+
#: (*singleton(Provider)) -> void
|
|
75
|
+
def register_providers(*provider_classes)
|
|
76
|
+
provider_classes.each { |klass| register_provider(klass) }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Returns the configuration instance
|
|
80
|
+
#
|
|
81
|
+
#: () -> Configuration
|
|
82
|
+
def configuration
|
|
83
|
+
@configuration ||= Configuration.new
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Configures SenroUsecaser
|
|
87
|
+
#
|
|
88
|
+
# @example
|
|
89
|
+
# SenroUsecaser.configure do |config|
|
|
90
|
+
# config.providers = [CoreProvider, UserProvider]
|
|
91
|
+
# config.infer_namespace_from_module = true
|
|
92
|
+
# end
|
|
93
|
+
#
|
|
94
|
+
#: () { (Configuration) -> void } -> void
|
|
95
|
+
def configure
|
|
96
|
+
yield configuration
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Boots all configured providers in dependency order
|
|
100
|
+
#
|
|
101
|
+
# @example
|
|
102
|
+
# SenroUsecaser.configure do |config|
|
|
103
|
+
# config.providers = [CoreProvider, UserProvider]
|
|
104
|
+
# end
|
|
105
|
+
# SenroUsecaser.boot!
|
|
106
|
+
#
|
|
107
|
+
#: () -> void
|
|
108
|
+
def boot!
|
|
109
|
+
@booter = ProviderBooter.new(configuration.providers, container)
|
|
110
|
+
@booter.boot!
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Shuts down all booted providers
|
|
114
|
+
#
|
|
115
|
+
#: () -> void
|
|
116
|
+
def shutdown!
|
|
117
|
+
@booter&.shutdown!
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Returns the current environment
|
|
121
|
+
#
|
|
122
|
+
# @example
|
|
123
|
+
# SenroUsecaser.env.development?
|
|
124
|
+
# SenroUsecaser.env.production?
|
|
125
|
+
#
|
|
126
|
+
#: () -> Environment
|
|
127
|
+
def env
|
|
128
|
+
@env ||= Environment.new(detect_environment)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Sets the environment
|
|
132
|
+
#
|
|
133
|
+
#: (String) -> void
|
|
134
|
+
def env=(name)
|
|
135
|
+
@env = Environment.new(name)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Resets all state (useful for testing)
|
|
139
|
+
#
|
|
140
|
+
#: () -> void
|
|
141
|
+
def reset!
|
|
142
|
+
@container = nil
|
|
143
|
+
@configuration = nil
|
|
144
|
+
@booter = nil
|
|
145
|
+
@env = nil
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
private
|
|
149
|
+
|
|
150
|
+
#: () -> String
|
|
151
|
+
def detect_environment
|
|
152
|
+
ENV["SENRO_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|