Giter Club home page Giter Club logo

dic's Introduction

uma/dic

CI Code Coverage

A PSR-11 container focused on human readability and comprehension.

Installation

$ composer require uma/dic:^4.0

Design Goals

Simplicity

A dependency injection container is a rather simple concept and its implementation should be simple, too.

PSR-11 compliance

It must implement the PSR-11 spec, and be usable wherever a PSR-11 container is to be expected.

Setter

It must have a standard way to add dependencies to the container as well as retrieve them. Using a Dependency Injection Container involves these two operations, not just getting them (I'm looking at you PSR-11).

To that end the Container class has a set method and also accepts an optional array of type string => mixed in its constructor, which is equivalent to calling set($id, $entry) with each of its key-value pairs.

Moreover, definitions have to be overridable, because definition overrides are a common approach in testing contexts.

$container = new UMA\DIC\Container([
  'host' => 'localhost',
  'port' => 8080
]);

$container->set('foo', 'bar');
$container->set('foo', 'baz');
var_dump($container->get('foo'));
// 'baz'

Lazy loading

It must be possible to register lazy services. These are services that are not instantiated until they are actually retrieved for the first time.

This library implements lazy services with anonymous functions. Whenever the container is asked for a service that is actually an anonymous function, that function is executed (passing the container itself as the first parameter) and the result is stored under the same id where the anonymous function used to be.

In addition, the container has a resolved method that returns whether a given service is an anonymous function or not. This can be useful when you need to assert whether a given service has been actually called (or not) on test code.

$container = new UMA\DIC\Container();
$container->set('dsn', '...');

// A database connection won't be made until/unless
// the 'db' service is fetched from the container
$container->set('db', static function(Psr\Container\ContainerInterface $c): \PDO {
  return new \PDO($c->get('dsn'));
});

var_dump($container->resolved('db'));
// false

$pdo = $container->get('db');

var_dump($container->resolved('db'));
// true

Providers

When a project involves large numbers of services these can be organized in Provider classes.

These classes implement UMA\DIC\ServiceProvider and receive an instance of the container in their provide method. They are then expected to register sets of related services in it. This concept is borrowed from Pimple.

$container = new UMA\DIC\Container();
$container->register(new Project\DIC\Repositories());
$container->register(new Project\DIC\Controllers());
$container->register(new Project\DIC\Routes());
$container->register(new Project\DIC\DebugRoutes());

Service Factories

In a few niche cases it can be desirable to create a new instance of the service every time it's requested from the container.

Like lazy loading, service factories are implemented using anonymous functions. However, they are registered with the factory method instead of set.

$container = new UMA\DIC\Container();

// Normal lazy loaded service. Will always return the
// same object instance after running the Closure once.
$container->set('foo', static function(): \stdClass {
  return new \stdClass();
});

// Factory service. The second argument must be a Closure.
// The closure will run every time the service is requested.
$container->factory('bar', static function(): \stdClass {
  return new \stdClass();
});

// foo is always the same object instance.
var_dump($container->get('foo') === $container->get('foo'));
// true

// bar is a different object instance each time it's requested.
var_dump($container->get('bar') === $container->get('bar'));
// false

dic's People

Contributors

1ma avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

dic's Issues

NotFound Exception

Hi !

What about a NotFoundException ?

When I try to get with a wrong idea, I have a strange error like "class@anonymous/DIR/vendor/uma/dic/src/Container.php0x7fecee803266" because of the call_user_func.

If you want, I can make a PR.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.