module Athena::DependencyInjection
Overview
Robust dependency injection service container framework.
Defined in:
annotation_configurations.crannotations.cr
athena-dependency_injection.cr
Constant Summary
-
VERSION =
"0.4.1"
Class Method Summary
-
.container : ADI::ServiceContainer
Returns the
ADI::ServiceContainer
for the current fiber.
Macro Summary
-
add_compiler_pass(pass, type = nil, priority = nil)
Adds a compiler pass, optionally of a specific type and priority (default
0
). -
bind(key, value)
Allows binding a value to a key in order to enable auto registration of that value.
-
configuration_annotation(name, *args, &)
Registers a configuration annotation with the provided name.
-
configure(config)
Primary entrypoint for configuring
ADI::Extension::Schema
s. -
register_extension(name, schema)
Registers an extension
ADI::Extension::Schema
with the provided name.
Class Method Detail
Returns the ADI::ServiceContainer
for the current fiber.
Macro Detail
Adds a compiler pass, optionally of a specific type and priority (default 0
).
Valid types include:
:before_optimization
(default):optimization
:before_removing
:after_removing
:removing
EXPERIMENTAL This feature is intended for internal/advanced use and, for now, comes with limited public documentation.
Allows binding a value to a key in order to enable auto registration of that value.
Bindings allow scalar values, or those that could not otherwise be handled via [service aliases][Athena::DependencyInjection::Register--aliasing-services], to be auto registered. This allows those arguments to be defined once and reused, as opposed to using named arguments to manually specify them for each service.
Bindings can also be declared with a type restriction to allow taking the type restriction of the argument into account. Typed bindings are always checked first as the most specific type is always preferred. If no typed bindings match the argument's type, then the last defined untyped bindings is used.
Example
module ValueInterface; end
@[ADI::Register(_value: 1, name: "value_one")]
@[ADI::Register(_value: 2, name: "value_two")]
@[ADI::Register(_value: 3, name: "value_three")]
record ValueService, value : Int32 do
include ValueInterface
end
# Untyped bindings
ADI.bind api_key, ENV["API_KEY"]
ADI.bind config, {id: 12_i64, active: true}
ADI.bind static_value, 123
ADI.bind odd_values, ["@value_one", "@value_three"]
ADI.bind value_arr, [true, true, false]
# Typed bindings
ADI.bind value_arr : Array(Int32), [1, 2, 3]
ADI.bind value_arr : Array(Float64), [1.0, 2.0, 3.0]
@[ADI::Register(public: true)]
record BindingClient,
api_key : String,
config : NamedTuple(id: Int64, active: Bool),
static_value : Int32,
odd_values : Array(ValueInterface)
@[ADI::Register(public: true)]
record IntArr, value_arr : Array(Int32)
@[ADI::Register(public: true)]
record FloatArr, value_arr : Array(Float64)
@[ADI::Register(public: true)]
record BoolArr, value_arr : Array(Bool)
ADI.container.binding_client # =>
# BindingClient(
# @api_key="123ABC",
# @config={id: 12, active: true},
# @static_value=123,
# @odd_values=[ValueService(@value=1), ValueService(@value=3)])
ADI.container.int_arr # => IntArr(@value_arr=[1, 2, 3])
ADI.container.float_arr # => FloatArr(@value_arr=[1.0, 2.0, 3.0])
ADI.container.bool_arr # => BoolArr(@value_arr=[true, true, false])
Registers a configuration annotation with the provided name. Defines a configuration record with the provided args, if any, that represents the possible arguments that the annotation accepts. May also be used with a block to add custom methods to the configuration record.
Example
# Defines an annotation without any arguments.
ADI.configuration_annotation Secure
# Defines annotation with a required and optional argument.
# The default value will be used if that key isn't supplied in the annotation.
ADI.configuration_annotation SomeAnn, id : Int32, debug : Bool = true
# A block can be used to define custom methods on the configuration object.
ADI.configuration_annotation CustomAnn, first_name : String, last_name : String do
def name : String
"#{@first_name} #{@last_name}"
end
end
NOTE The logic to actually do the resolution of the annotations must be handled in the owning shard.
Athena::DependencyInjection
only defines the common logic that each implementation can use.
See ADI::AnnotationConfigurations
for more information.
Registers an extension ADI::Extension::Schema
with the provided name.