Crystal-DI is a flexible DI-container with simple DSL, auto-injection, memoization, lazy evaluation and contextual bindings.
Add this to your application's shard.yml
:
dependencies:
di:
github: funk-yourself/crystal-di
version: ~> 0.2.1
It's as simple as:
require "di"
module Container # may be a class as well
include DI::ContainerMixin
register Foo, Foo.new
end
Container.resolve(Foo)
You can also use blocks:
register Bar, Bar.new
register Foo do
logger = Logger.new(STDOUT)
logger.level = Logger::WARN
Foo.new(resolve(Bar), logger)
end
module Container
include DI::ContainerMixin
register AppService, AppService.new
end
class AppService
end
class Controller
include DI::AutoInject(Container)
def initialize(@app_service : AppService)
p @app_service
end
end
Controller.new
Sometimes you need to be sure that there's only one instance of some service. You can achieve that with memoize option:
# Will be evaluated only one time
register AppService, AppService.new, memoize: true
You can bind container items to any class with context option:
register AppService, AppService.new, context: Controller
It means that you can resolve this item by calling
Container.resolve(AppService, context: Controller)
But the main purpose is ability to auto-inject different implementations of abstract class/interface into different classes:
require "di"
module Container
include DI::ContainerMixin
register Storage, RedisStorage.new, context: UsersController
register Storage, MemcachedStorage.new, context: PostsController
end
abstract class Storage
end
class RedisStorage < Storage
end
class MemcachedStorage < Storage
end
class UsersController
include DI::AutoInject(Container)
def initialize(@storage : Storage)
p @storage
end
end
class PostsController
include DI::AutoInject(Container)
def initialize(@storage : Storage)
p @storage
end
end
UsersController.new # will print RedisStorage
PostsController.new # will print MemcachedStorage
Run tests:
crystal spec
- Fork it ( https://github.com/funk-yourself/crystal-di/fork )
- Create your feature branch (git checkout -b my-new-feature)
- Commit your changes (git commit -am 'Add some feature')
- Push to the branch (git push origin my-new-feature)
- Create a new Pull Request
- funk-yourself (Vladislav Yashin) - creator, maintainer