-
Notifications
You must be signed in to change notification settings - Fork 1
/
service_container.cr
104 lines (90 loc) · 2.72 KB
/
service_container.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
class Athena::DependencyInjection::ServiceContainer; end
require "./compiler_passes/*"
# Where the instantiated services live.
#
# If a service is public, a getter based on the service's name as well as its type is defined. Otherwise, services are only available via constructor DI.
#
# TODO: Reduce the amount of duplication when [this issue](https://github.com/crystal-lang/crystal/pull/9091) is resolved.
class Athena::DependencyInjection::ServiceContainer
# :nodoc:
#
# Define a hash to store services while the container is being built
# Key is the ID of the service and the value is another hash containing its arguments, type, etc.
SERVICE_HASH = {} of Nil => Nil
# :nodoc:
#
# Maps services to their aliases
#
# Hash(String, NamedTuple(id: String, public: Bool))
ALIASES = {} of Nil => Nil
# Define a hash to store the service ids for each tag.
#
# Tag Name, service_id, array attributes
# Hash(String, Hash(String, Array(NamedTuple)))
private TAG_HASH = {} of Nil => Nil
# :nodoc:
EXTENSIONS = {} of Nil => Nil
# :nodoc:
#
# Holds the compiler pass configuration, including the type of each pass, and the default order the built-in ones execute in.
PASS_CONFIG = {
# Global pre-optimization modules
# Sets up common concepts so that future passes can leverage them
before_optimization: {
1028 => [
# Ensure merged configuration is available
MergeConfigs,
MergeExtensionConfig,
],
100 => [
NormalizeDefinitions,
RegisterServices,
ProcessAliases,
ProcessAutoconfigureAnnotations,
ProcessParameters,
ValidateGenerics,
],
},
# Prepare the services for usage by resolving arguments, parameters, and ensure validity of each service
optimization: {
0 => [
ResolveParameterPlaceholders,
ProcessBindings,
ProcessAnnotationBindings,
AutoWire,
ResolveTaggedIterators,
ResolveValues,
ValidateArguments,
],
},
# Determine what could be removed?
before_removing: {
0 => [] of Nil,
},
# Cleanup the container, removing unused services and such
removing: {
0 => [] of Nil,
},
# Codegen things that create types/methods within the container instance, such as the getters for each service
after_removing: {
-100 => [
DefineGetters,
],
},
}
macro finished
{%
passes = [] of Nil
PASS_CONFIG.keys.each do |type|
(p = PASS_CONFIG[type]).keys.sort_by { |tk| -tk }.each do |k|
p[k].each do |pass|
passes << pass
end
end
end
%}
{% for pass in passes %}
include {{pass.id}}
{% end %}
end
end