Class: Needle::ServicePoint

Inherits:
Object
  • Object
show all
Defined in:
lib/needle/service-point.rb

Overview

A “service point” is a definition of a service. Just as a class defines the behavior of an object, so does a service point describes a service. In particular, a service point also knows how to instantiate a service.

A ServicePoint should never be directly instantiated. Instead, define services via the interfaces provided by Container.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(container, name, opts = {}, &callback) ⇒ ServicePoint

Create a new service point that references the given container and has the given name. The associated callback will be used to instantiate the service on demand.

The :model option is used to tell Needle which style of life-cycle management should be used for the service. It defaults to :singleton. The model must be a symbol that refers to a service model that has been registered in the root :service_models service.

The :pipeline option is mutually exclusive with :model. It must be an array of symbols (or strings) that define the instantiation pipeline to use for this service. Each element must correspond to an entry in the :pipeline_elements service.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/needle/service-point.rb', line 54

def initialize( container, name, opts={}, &callback )
  @name = name
  @container = container
  @callback = callback
  @pipeline = Needle::Pipeline::Collection.new self
  @chain = nil
  @mutex = QueryableMutex.new

  if opts[:pipeline]
    elements = opts[:pipeline]
  else
    model = opts[:model] || :singleton
    elements = @container[:service_models][model]
  end

  elements.each { |element| @pipeline.add element, opts }
end

Instance Attribute Details

#containerObject (readonly)

A reference to the container that contains this service point.



35
36
37
# File 'lib/needle/service-point.rb', line 35

def container
  @container
end

#nameObject (readonly)

The name of this service point, as it is known to the container that it was registered in.



32
33
34
# File 'lib/needle/service-point.rb', line 32

def name
  @name
end

#pipelineObject (readonly)

The reference to the instantiation pipeline used by this service point.



38
39
40
# File 'lib/needle/service-point.rb', line 38

def pipeline
  @pipeline
end

Instance Method Details

#fullnameObject

Returns the fully-qualified name of the service point, with the point’s name, its container’s name, and all of its container’s ancestors’ names concatenated together with dot characters, i.e. “one.two.three”.



75
76
77
78
79
80
81
82
# File 'lib/needle/service-point.rb', line 75

def fullname
  container_name = @container.fullname
  if container_name
    "#{container_name}.#{@name}"
  else
    @name.to_s
  end
end

#instanceObject

Return the service instance represented by this service point. Depending on the style of lifecycle management chosen for this service point, this may or may not be a new instance for every invocation of this method.



99
100
101
102
103
104
105
106
107
# File 'lib/needle/service-point.rb', line 99

def instance
  unless @chain
    @mutex.synchronize do
      @chain = @pipeline.chain_to( @callback ) unless @chain
    end
  end

  @chain.call( @container, self )
end

#interceptor(interceptor) ⇒ Object

Adds the given interceptor definition to this service point. The parameter should act like an instance of Interceptor.



86
87
88
89
90
91
92
93
94
# File 'lib/needle/service-point.rb', line 86

def interceptor( interceptor )
  element = @pipeline.get( :interceptor )
  unless element
    @chain = nil
    @pipeline.add( :interceptor )
    element = @pipeline.get( :interceptor )
  end
  element.interceptors << interceptor
end