README.md
# SmartIoC
[![Build Status](https://travis-ci.org/ddd-ruby/smart_ioc.png)](https://travis-ci.org/ddd-ruby/smart_ioc)
[![Code Climate](https://codeclimate.com/github/ddd-ruby/smart_ioc/badges/gpa.svg)](https://codeclimate.com/github/ddd-ruby/smart_ioc)
[![codecov](https://codecov.io/gh/ddd-ruby/smart_ioc/branch/master/graph/badge.svg)](https://codecov.io/gh/ddd-ruby/smart_ioc)
[![Dependency Status](https://gemnasium.com/ddd-ruby/smart_ioc.png)](https://gemnasium.com/ddd-ruby/smart_ioc)
SmartIoC is a smart and really simple IoC container for Ruby applications.
## Installation
`gem install smart_ioc`
## Setup
Set package name and source package folder with beans. SmartIoC will parse source files and detect bean definitions automatically for you.
```ruby
SmartIoC.find_package_beans(:PACKAGE_NAME, File.dirname(__FILE__))
```
If you have several packages in your application (like if you are using [rdm package manager](https://github.com/droidlabs/rdm)) you can run SmartIoC.find_package_beans several time pointing it to the source folder and setting a different package name.
## Basic information
1. Different packages can use beans with same name.
2. For a specific package you can declare beans with same name if they have different context.
```ruby
class UsersRepository
include SmartIoC::Iocify
bean :users_repository
end
class Test::UsersRepository
include SmartIoC::Iocify
bean :users_repository, context: :test
end
```
3. You can extend the `:default` context with any other in the following way:
```ruby
SmartIoC::Container.get_instance.set_extra_context_for_package(:YOUR_PACKAGE_NAME, :test)
```
This allows to create test implementations for any package dependency.
4. In order to get a bean use `SmartIoC::Container.get_bean(:BEAN_NAME, package: :PACKAGE_NAME, context: :default)`. `package` and `context` are optional arguments.
5. If you use the same bean name for different dependencies in different packages you will need to specify the package directly. You can do that by using `from` parameter:
```ruby
class UsersCreator
include SmartIoC::Iocify
bean :users_creator
inject :users_repository, from: :repositories
def create
user = User.new
users_repository.put(user)
end
end
```
6. To have a diffent local name for a specific bean use the `ref` parameter.
In the following example we are injecting the `:users_repository` dependency but refer to it as `repo` locally.
```ruby
class UsersCreator
include SmartIoC::Iocify
bean :users_creator
inject :users_repository, ref: :repo, from: :repositories
def create
user = User.new
repo.put(user)
end
end
```
7. Use factory method to instantiate the bean via a special creational method
```ruby
class RepositoryFactory
include SmartIoC::Iocify
bean :users_creator, factory_method: :get_bean
inject :config
inject :users_repository
inject :admins_repository
def get_bean
if config.admin_access?
admins_repository
else
users_repository
end
end
def create
user = User.new
repo.put(user)
end
end
```
8. Class level beans (object will not be instantiated and class will be used for that bean instead). Set `instance: false`:
```ruby
class UsersCreator
include SmartIoC::Iocify
bean :users_creator, instance: false
inject :users_repository
end
```