Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fabrique

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fabrique

  • 1.0.2
  • Rubygems
  • Socket score

Version published
Maintainers
1
Created
Source

Gem Version Build Status Dependency Status

Fabrique

Configuration-based factory for dependency injection. Inspired by Java spring beans.

Installation

Add this line to your application's Gemfile:

gem 'fabrique'

And then execute:

$ bundle

Or install it yourself as:

$ gem install fabrique

Testing

git clone git@github.com/starjuice/fabrique.git
cd fabrique
bundle
bundle exec rake

The test coverage is superficial at the moment. When working with features/bean_factory.feature, keep in mind that some exceptions are caught and stored as instance variables to be evlauated by subsequent steps. This avoids some English contortions, but the down side is that if you introduce a regression that raises an exception in a scenario that doesn't expect one, you won't see the exception. To log exceptions, even when they are expected:

DEBUG=1 bundle exec rake

Usage

Under construction; hard hat required!

The best source of documentation of what's possible in the configuration of Fabrique::BeanFactory is currently features/bean_factory.feature. But reading the step definitions for an example of usage would be awkward, so here is a code example.

Given this example YAML application context definition, in a file called application_context.yml:

---
beans:
- id: customer_repository
  class: Acme::Repository::CustomerRepository
  constructor_args:
    - !bean/ref store
    - !bean/ref customer_data_mapper
- id: product_repository
  class: Acme::Repository::ProductRepository
  constructor_args:
    store: !bean/ref store
    data_mapper: !bean/ref product_data_mapper
- id: store
  class: Acme::Repository::MysqlStore
  constructor_args:
    host: localhost
    port: 3306
  gem:
    name: acme-repository-mysql_store
    version: "~> 1.0"
    require: "acme/repository/mysql_store"
- id: customer_data_mapper
  class: Acme::Repository::MysqlDataMapper::Customer
  gem:
    name: acme-repository-mysql_data_mapper
    require: acme/repository/mysql_data_mapper/customer
- id: product_data_mapper
  class: Acme::Repository::MysqlDataMapper::Product
  gem:
    name: acme-repository-mysql_data_mapper
    require: acme/repository/mysql_data_mapper/product

Here is how we could materialize these dependencies:

bean_factory = Fabrique::YamlBeanFactory.new(File.read('application_context.yml'))
bean_factory.load_gem_dependencies

customer_service = CustomerService.new(repository: bean_factory.get_bean('customer_repository'))
product_service = ProductService.new(repository: bean_factory.get_bean('product_repository'))
store_service = StoreService.new(customers: customer_service, products: product_service)
# ...

Of course, the construction of these services could just as well have been handled by the bean factory as well. Where to draw the line is an interesting topic. The example above draws it "at dependencies that could be expected to vary per deployment".

Notice that gems were only specified for the parts of the context that could be expected to vary per deployment; the gem providing Acme::Repository::CustomerRepository and Acme::Repository::ProductRepository would be bundled with the application.

Also notice that the gem loader is activated by an explicit call to load_gem_dependencies. Runtime installation and activation of gems is controversial, and so it must be requested explicitly.

For a data-centric approach to IoC, the entire set of beans can be materialized as a dictionary and made available to consumer to cherry-pick what they need without any awareness of the use of a BeanFactory:

bean_factory = Fabrique::YamlBeanFactory.new('application_context.yml')
bean_factory.load_gem_dependencies

# Symbolize keys for use as keyword arguments:
context = bean_factory.to_h.map { |k, v| [k.intern, v] }.to_h

store_service = StoreService.new(context)

FAQs

Package last updated on 06 Mar 2017

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc