Sha256: 24fb69bf7036d88e51bb924f7c424a987e62fb72053855c869ff02cae9e46aeb

Contents?: true

Size: 1.61 KB

Versions: 1

Compression:

Stored size: 1.61 KB

Contents

module Invokr
  module DependencyInjection
    extend self

    def inject obj, using
      meth = case obj
             when Proc then :inject_proc
             when Class then :inject_klass
             else raise ArgumentError, "can't inject #{obj.inspect}"
             end
      resolver = build_resolver using
      send meth, obj, resolver
    end

    private

    def build_resolver using
      if using.is_a? Hash
        HashResolver.new using
      else
        using
      end
    end

    def inject_klass klass, resolver
      injector = KlassInjector.new resolver, klass
      injector.inject
    end

    def inject_proc proc, resolver
      injector = ProcInjector.new resolver, proc
      injector.inject
    end

    Injector = Struct.new :resolver, :obj do
      def keys
        method.parameters.map { |_, identifier| identifier }
      end

      def fetch arg, &default
        resolver.resolve arg, &default
      end
    end

    class KlassInjector < Injector
      def inject
        _method = Invokr.query_method method
        _method.invoke :method => :new, :with => self
      end

      def method
        obj.instance_method :initialize
      end
    end

    class ProcInjector < Injector
      def inject
        Invokr.invoke :proc => obj, :with => self
      end

      def method
        obj
      end
    end

    class HashResolver
      def initialize hsh
        @hsh = hsh
      end

      def inject klass
        DependencyInjection.inject(
          :klass => klass,
          :using => self,
        )
      end

      def resolve val, &block
        @hsh.fetch val, &block
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
invokr-0.9.1 lib/invokr/dependency_injection.rb