Crystal-DI alternatives and similar shards
Based on the "Framework Components" category.
Alternatively, view Crystal-DI alternatives based on common mentions on social networks and blogs.
-
motion.cr
Motion is a framework for building reactive, real-time frontend UI components in your Amber application using pure Crystal that are reusable, testable & encapsulated. -
mochi
Mochi is a authentication shard inspired by devise. Mochi is designed for the Amber framework with support for both Granite & Jennifer ORM's.
CodeRabbit: AI Code Reviews for Developers
Do you think we are missing an alternative of Crystal-DI or a related project?
README
Lightweight DI Container for Crystal
Crystal-DI is a flexible DI-container with simple DSL, auto-injection, memoization, lazy evaluation and contextual bindings.
Installation
Add this to your application's shard.yml
:
dependencies:
di:
github: funk-yourself/crystal-di
version: ~> 0.2.1
Usage
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
Auto-injection
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
Memoization
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
Contextual bindings
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
Development
Run tests:
crystal spec
Contributing
- 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
Contributors
- funk-yourself (Vladislav Yashin) - creator, maintainer