class IocRb::BeanFactory

Instantiates beans according to their scopes

Attributes

const_loader[R]

Public Class Methods

new(const_loader, beans_metadata_storage) click to toggle source

Constructor @param beans_metadata_storage [BeansMetadataStorage] storage of bean metadatas

# File lib/ioc_rb/bean_factory.rb, line 12
def initialize(const_loader, beans_metadata_storage)
  @const_loader           = const_loader
  @beans_metadata_storage = beans_metadata_storage
  @singleton_scope        = IocRb::Scopes::SingletonScope.new(self)
  @prototype_scope        = IocRb::Scopes::PrototypeScope.new(self)
  @request_scope          = IocRb::Scopes::RequestScope.new(self)
end

Public Instance Methods

create_bean_and_save(bean_metadata, beans_storage) click to toggle source

Create new bean instance according to the specified bean_metadata @param [BeanMetadata] bean metadata @return bean instance @raise MissingBeanError if some of bean dependencies are not found

# File lib/ioc_rb/bean_factory.rb, line 46
def create_bean_and_save(bean_metadata, beans_storage)
  if bean_metadata.bean_class.is_a?(Class)
    bean_class = bean_metadata.bean_class
  else
    bean_class = const_loader.load_const(bean_metadata.bean_class)
    bean_metadata.fetch_attrs!(bean_class)
  end
  bean = bean_metadata.instance ? bean_class.new : bean_class
  if bean_metadata.has_factory_method?
    set_bean_dependencies(bean, bean_metadata)
    bean = bean.send(bean_metadata.factory_method)
    beans_storage[bean_metadata.name] = bean
  else
    # put to container first to prevent circular dependencies
    beans_storage[bean_metadata.name] = bean
    set_bean_dependencies(bean, bean_metadata)
  end

  bean
end
delete_bean(name) click to toggle source

Delete bean from the container by it's name. @param [Symbol] bean name @raise MissingBeanError if bean with the specified name is not found

# File lib/ioc_rb/bean_factory.rb, line 70
def delete_bean(name)
  bean_metadata = @beans_metadata_storage.by_name(name)
  unless bean_metadata
    raise IocRb::Errors::MissingBeanError, "Bean with name :#{name} is not defined"
  end
  get_scope_by_metadata(bean_metadata).delete_bean(bean_metadata)
end
get_bean(name) click to toggle source

Get bean from the container by it's name. According to the bean scope it will be newly created or returned already instantiated bean @param [Symbol] bean name @return bean instance @raise MissingBeanError if bean with the specified name is not found

# File lib/ioc_rb/bean_factory.rb, line 26
def get_bean(name)
  bean_metadata = @beans_metadata_storage.by_name(name)
  unless bean_metadata
    raise IocRb::Errors::MissingBeanError, "Bean with name :#{name} is not defined"
  end
  get_bean_with_metadata(bean_metadata)
end
get_bean_with_metadata(bean_metadata) click to toggle source

Get bean by the specified +bean metadata+ @param [BeanMetadata] bean metadata @return bean instance

# File lib/ioc_rb/bean_factory.rb, line 37
def get_bean_with_metadata(bean_metadata)
  get_scope_by_metadata(bean_metadata).get_bean(bean_metadata)
end

Private Instance Methods

get_scope_by_metadata(bean_metadata) click to toggle source
# File lib/ioc_rb/bean_factory.rb, line 103
def get_scope_by_metadata(bean_metadata)
  case bean_metadata.scope
  when :singleton
    @singleton_scope
  when :prototype
    @prototype_scope
  when :request
    @request_scope
  else
    raise IocRb::Errors::UnsupportedScopeError, "Bean with name :#{bean_metadata.name} has unsupported scope :#{bean_metadata.scope}"
  end
end
set_bean_dependencies(bean, bean_metadata) click to toggle source
# File lib/ioc_rb/bean_factory.rb, line 80
def set_bean_dependencies(bean, bean_metadata)
  bean_metadata.attrs.each do |attr|
    bean_metadata = @beans_metadata_storage.by_name(attr.ref)
    unless bean_metadata
      raise IocRb::Errors::MissingBeanError, "Bean with name :#{attr.ref} is not defined, check #{bean.class}"
    end
    case bean_metadata.scope
    when :singleton
      bean.send("#{attr.name}=", get_bean(attr.ref))
    when :prototype
      bean.instance_variable_set(:@_ioc_rb_bean_factory, self)
      bean.define_singleton_method(attr.name) do
        @_ioc_rb_bean_factory.get_bean(attr.ref)
      end
    when :request
      bean.instance_variable_set(:@_ioc_rb_bean_factory, self)
      bean.define_singleton_method(attr.name) do
        @_ioc_rb_bean_factory.get_bean(attr.ref)
      end
    end
  end
end