Wireless

Build Status Gem Version

NAME

Wireless - a lightweight, declarative dependency-provider

INSTALLATION

gem "wireless"

SYNOPSIS

require "wireless"

WL = Wireless.new do
  count = 0

  # factory: return a new value every time
  on(:foo) do
    [:foo, count += 1]
  end

  # singleton: return the cached value
  once(:bar) do
    [:bar, 42]
  end

  # depend on other dependencies
  on(:baz) do |wl|
    [:baz, wl[:foo], wl[:bar]]
  end
end

# factory
WL[:foo] # [:foo, 1]
WL[:foo] # [:foo, 2]

# singleton
WL[:bar] # [:bar, 42]
WL[:bar] # [:bar, 42]

# dependencies
WL[:baz] # [:baz, [:foo, 3], [:bar, 42]]
WL[:baz] # [:baz, [:foo, 4], [:bar, 42]]

# mixin
class Example
  include WL.mixin %i[foo bar baz]

  def test
    foo # [:foo, 5]
    bar # [:bar, 42]
    baz # [:baz, [:foo, 6], [:bar, 42]]
  end
end

DESCRIPTION

Wireless is a declarative dependency-provider (AKA service locator), which has the following features:

  • Simplicity

    It's just an object which dependencies can be added to and retrieved from. It can be passed around and stored like any other object. No "injection", containers, framework, or dependencies.

  • Convenience

    Include dependency getters into a class or module with control over their visibility.

  • Laziness

    As well as being resolved lazily, dependencies can also be registered lazily, i.e. at the point of creation. There's no need to declare everything up front.

  • Safety

    Dependency resolution is thread-safe. Dependency cycles are checked and raise a fatal error as soon as they are detected.

WHY?

Why Wireless?

I wanted a simple service locator like DiFtw, with cycle detection and control over the visibility of getters.

Why Service Locators?

Service locators make it easy to handle shared (AKA cross-cutting) dependencies i.e. values and services that are required by multiple otherwise-unrelated parts of a system. Examples include:

  • logging
  • configuration data
  • storage backends
  • authorisation

Rather than wiring these dependencies together manually, service locators allow them to be registered and retrieved in a declarative way. This is similar to the difference between imperative build tools like Ant or Gulp, and declarative build tools like Make or Rake, which allow prerequisites to be acquired without coordinating their construction.

COMPATIBILITY

VERSION

0.1.0

SEE ALSO

Gems

  • Canister - a simple service-locator inspired by Jim Weirich's article on Dependency Injection
  • DiFtw - the original inspiration for this module: a similar API with a focus on testing/mocking
  • dry-container - a standalone service-locator which can also be paired with a dependency injector

Articles

AUTHOR

chocolateboy

COPYRIGHT AND LICENSE

Copyright © 2018-2020 by chocolateboy.

This is free software; you can redistribute it and/or modify it under the terms of the Artistic License 2.0.