Chapter 3. S2Container.Ruby Reference

Table of Contents

3.1. S2Container Reference
3.1.1. Generation of S2Container
3.1.2. Getting a component
3.1.3. Dependency Injection
3.1.4. Constructor Block
3.1.5. Destructor Block
3.1.6. Binding type setup
3.1.7. Instance type setup
3.2. S2ApplicationContext Reference
3.2.1. Generation of S2ApplicationContext
3.2.2. Registration of a component
3.2.3. Generation of S2Container
3.2.4. Selection of a component
3.2.5. Auto Aspect
3.2.6. Management of Singleton S2Container instance

3.1. S2Container Reference

3.1.1. Generation of S2Container

Generation of S2Container is carried out by the "create" method of S2ApplicationContext class.

require 's2container'
container = Seasar::Container::S2ApplicationContext.instance.create

By using the s2app method which returns S2ApplicationContext instance, S2Container is generable as follows.

require 's2container'
container = s2app.create

3.1.2. Getting a component

The following method is used in order to take out a component from S2Container.

S2Container#get_component(component_key)

The class name or component name of a component is specified as an argument.
When there are two or more components which indicates the class specified in S2Container, Since S2Container cannot judge which component should be returned, it carries out a raise of the exception "TooManyRegistrationRuntimeException". Therefore, please specify the class name it is decided uniquely that a component will be.
It is also the same as when taking out a component by a component name.

As an example, The following classes are defined. A component name is set up by a character string and Symbol by the argument of the s2component method.

module Example
  class IndexAction
    s2component :name => "index"
  end

  class TopAction
    s2component :name => :top
  end

  class ResultAction
    s2component
  end
end

It is as follows, when specifying a component name by a character string and getting a component.

require 's2container'
require 'example'
container = s2app.create
component = container.get_component("index")

It is as follows, when specifying a component by Class and getting a component. The component method is alias of the get_component method.

component = container.component(Example::IndexAction)

It is as follows, when specifying a component by Symbol and getting a component. The get method is alias of the get_component method.

component = container.get(:top)

[] can also be used as a method which gets a component from S2Contaienr.

component = container[Example::ResultAction]
[Note]NOTE

This Example is located at "example/example01".


3.1.3. Dependency Injection

Dependency Injection of S2Container is the property injection by automatic binding. Instance variables and accessor methods are treated as a property. Automatic binding solves the dependency between components by the property name and by the class and component name which are specified by the default value of a property.

Let's define following classes. The constructor (initialize method) of Action class defines instance variables. The dependence information on Action and Service component is set up as a default value of an instance variable. Moreover, since the attr_accessor method defines the property "d", the component named "d" will be injected.

module Example
  class Action
    s2comp
    def initialize
      @a = nil
      @b = :di, "x.y.z.service_b"
      @c = :di, ServiceC
      @x_ = nil
      @_x = nil
    end
    attr_reader :a, :b, :c
    attr_accessor :d
  end

  class ServiceA
    s2comp :name => :a
  end

  class ServiceB
    s2comp :name => "service_b", :namespace => "x.y.z"
  end

  class ServiceC
    s2comp
  end

  class ServiceD
    s2comp :name => :d
  end
end

Please create the following executable files. when Action component is taken out from S2Container, Dependent Service component will be injected to the instance variables of the Action component.

require 's2container'
require 'example'

container = s2app.create
component = container[Example::Action]

The instance variable to which the underscore was attached a head or behind the variable name is not bound automatically. How to set up the dependency between components by the default value of a property is shown below.

Table 3.1. Property value and DI

Property valueExplanationExample
nil The Symbol of an instance variable name is used as a component key. A component name is set to ":a" when an instance variable name is "@a." @property = nil
Array When the size of Array is 2 and the first value is "di" (String or Symbol), uses the second value as a component key. @property = :di, "service"

[Note]NOTE

This Example is located at "example/example02".


3.1.4. Constructor Block

Constructor Block is a block which performs generation processing of a component. Constructor Block is set up when registering a component by the s2component method.

Let's define the following classes.

module Example
  class Action
    def initialize(val)
      @val = val
    end
    attr_accessof :val
  end
end

Please create the following executable files. Constructor Block is passed to the s2component method. The evaluation result of the last of Constructor Block must fulfill the relation of is_a? with a component class.

require 's2container'
require 'example'

s2component(:class => Example::Action) {
  Example::Action.new("abc")
} 

container = s2app.create
component = container[Example::Action]
p component.val          # -> "abc" 
[Note]NOTE

This Example is located at "example/example03".


3.1.5. Destructor Block

Constructor Block is a block which performs destroy processing of a component. When the instance setting of the component is ":singleton", thr destructor block is executed. The destructor block is executed in the destroy method of s2container.

Let's define the following classes.

module Example
  class Action
    def init
      s2logger.debug(self.class){"init method called as constructor."}
    end
    def quit
      s2logger.debug(self.class){"quit method called as destructor."}
    end
  end
end

Please create the following executable files. The component is registered by the s2component method. The destructor block is set to the return value(ComponentInfoDef instance) of the s2component method.

require 's2container'
require 'example'

component_info = s2component(:class => Example::Action) {
  # constructor block
  action = Example::Action.new
  action.init
  next action
}

component_info.destructor {|component|
  # destructor block
  component.quit
}

container = s2app.create
container.init                     # call constructor block
container.destroy                  # call destructor block


3.1.6. Binding type setup

In S2Container, a binding type can be specified per component.

Table 3.2. Binding Type

autoBindingExplanation
:auto (default) It binds automatically by the default value of a property.
:none It is followed when the argument of the constructor is specified clearly.
It is followed when the property is specified clearly.

It is as follows when specifying a binding type by the s2component method.

class Service
  s2component :autobinding => :auto
end

3.1.7. Instance type setup

In S2Container, instance management can be specified per component.

Table 3.3. Instance Type

instanceExplanation
:singleton (default) Getting a component by S2Container.get_component method will return the always same instance.
:prototype A new instance is returned whenever it gets a component by S2Container.get_component method.

It is as follows when specifying an instance type by the s2component method.

class Service
  s2component :instance => :singleton
end


© Copyright The Seasar Foundation and the others 2008-2009, all rights reserved.