Code Monkey home page Code Monkey logo

di's Introduction

Nette Framework is a popular tool for PHP web development. It is designed to be as usable and as friendly as possible. It focuses on security and performance and is definitely one of the safest PHP frameworks.

Nette Framework speaks your language and helps you to easily build better websites.

The Quick Start tutorial gives you a first introduction to the framework by creating a simple database driven application.

Over 10 Yrs of Development

We have been developing Nette for over 10 years- and counting! Libraries we provide are therefore highly mature, stable and widely used. They are trusted by a number of global corporations and many significant websites rely on us.

Catching Bronze

We aim to create Nette as a fun and easy to use framework, that programmers can fall in love with. And we seem to be doing it well! We were rated as the 3rd most popular framework in a survey Best PHP Framework for 2015 by a well-know magazine SitePoint.

Security Is a Priority

There is nothing we care about more than security. That is why we had built Nette as the safest PHP framework. It had passed many audits with flying colours, it eliminates safety traps like XSS, CSRF and brings out ground-breaking methods.

Libraries & Framework

Nette consists of a number of handy standalone libraries, which can be used in any codebase, for example combined with WordPress or another framework. Careful, some of them are highly addictive! These are the components that Nette Framework is built on:

  • Application – The kernel of web application
  • Bootstrap – Bootstrap of your application
  • Caching – Cache layer with set of storages
  • Component Model – Foundation for component systems
  • DI – Dependency Injection Container
  • Finder – Find files and directories with an intuitive API
  • Database – Database layer
  • Forms – Greatly facilitates secure web forms
  • Http – Layer for the HTTP request & response
  • Latte – Amazing template engine
  • Mail – Sending E-mails
  • Neon – Loads and dumps NEON format
  • Php Generator – PHP code generator
  • Robot Loader – The most comfortable autoloading
  • Routing – Routing
  • Safe Stream – Safe atomic operations with files
  • Security – Provides access control system
  • Schema – User data validation
  • Tester – Enjoyable unit testing in PHP
  • Tracy – Debugging tool you will love ♥
  • Tokenizer – Source code tokenizer
  • Utils – Utilities and Core Classes

di's People

Contributors

adaamz avatar dg avatar enumag avatar f3l1x avatar fprochazka avatar greeny avatar h4kuna avatar hrach avatar janbarasek avatar jantvrdik avatar kravco avatar kukulich avatar lookyman avatar majkl578 avatar matej21 avatar milanpala avatar milo avatar ondrahb avatar ondrejmirtes avatar pavelkouril avatar pmachan avatar rixafy avatar sallyx avatar tomasvotruba avatar tomaswindsor avatar uestla avatar vasekpurchart avatar vrana avatar vrtak-cz avatar xificurk avatar

Stargazers

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

Watchers

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

di's Issues

Performance issue of magic methods, getters and setters

I was wondering what takes so long while nette is generating container. And surprisingly (or not?) - it's a magic!
This is xdebug profiler output for my app:
di-magie2
(self and inclusive cost is in percent)

I've tried to make some optimization (replacing magic @method in nette/di and nette/phpgenerator with proper methods and removing usage of magic getters/setters) and this is the result:
di-magie3

Ouch!

Do you agree with removing this magic? Should I prepare PR?

mysqli creation requires to specify all arguments

After migrating to version 2.3 I'm getting error Parameter $port in mysqli::mysqli() has no type hint, so its value must be specified when creating mysqli (it has default values taken from ini settings) like this:

    - mysqli(
        %database.host%,
        %database.username%,
        %database.password%,
        %database.database%
    )

This definitly worked on 2.2. To make it work as before, I must use:

    - mysqli(
        %database.host%,
        %database.username%,
        %database.password%,
        %database.database%,
        ::ini_get(mysqli.default_port),
        ::ini_get(mysqli.default_socket)
    )

Generated factory cannot be overwritten

Let's have following setup

namespace My;

class Generated {}
interface IGeneratedFactory {
    /** @return Generated */ public function create();
}
services:
    a: My\IGeneratedFactory

Now image I wanna replace the instance of the factory.

$mock = \Mockery::mock(My\IGeneratedFactory::class);
$container->addService('a', $mock);

This throws unexpected exception, that type My\Generated was expected, but My\IGeneratedFactory was provided.


I'm using 9799449, so I'm not sure if this wasn't fixed already.

Better exception with typo in service definition.

- 
    class: \MyClass
    autowire: false

produces: Unknown or deprecated key 'autowire' in definition of service.

Would be great to directly say if it's deprecated, or something like "did you mean" :-)

Občas nemůže otevřít Nette.Configurator/Container_0000f000f0.php

Ahoj,
obcas v průběhu používání applikace se mi stane, že dostanu http://postimg.org/image/qokdch9lj/
Není to třeba žebych smazal cache a pak se to dělo, na jedné stránce při práci s ní po několika refreshích se mu to prostě občas nepodaří otevřít.

Abych řekl pravdu, absolutně netuším jak to debugovat, ale když se podívám na disk tak tam ten file fyzicky existuje. Kdyby byl nějaký tip jak to pozorovat tak rád pomohu více.

ContainerLoader - implode(): Invalid arguments passed

PHP: 7.0
nette/di: 2.4.0


This snippet of code triggered error.

    $loader = new ContainerLoader(TEMP_DIR, TRUE);
    $class = $loader->load(function (Compiler $compiler) {
        $compiler->addExtension('a', new FoobarExtension);
    }, 'foobar');
   Exited with error code 255 (expected 0)
   E_WARNING: implode(): Invalid arguments passed

   in src/DI/ContainerLoader.php(119) 
   in src/DI/ContainerLoader.php(119) implode()
   in src/DI/ContainerLoader.php(82) Nette\DI\ContainerLoader->generate()
   in src/DI/ContainerLoader.php(47) Nette\DI\ContainerLoader->loadFile()

I think that problem might be here (double implode).

https://github.com/nette/di/blob/v2.4.0/src/DI/Compiler.php#L161
https://github.com/nette/di/blob/v2.4.0/src/DI/ContainerLoader.php#L119


Is it wrong usage or it is really bug? :-)

Broken InjectExtension with removed definition

#71 #72 broke InjectExtension. When another extension override definition with own definition, it removes class from $classes, but ->addDefinition does not add new.

certain description (see link):

  1. $classes is prepared by https://github.com/nette/di/blob/master/src/DI/Compiler.php#L202
  2. OrmExtension override definition https://github.com/Kdyby/Doctrine/blob/master/src/Kdyby/Doctrine/DI/OrmExtension.php#L741 (beforeCompile) - remove $classes https://github.com/nette/di/blob/master/src/DI/ContainerBuilder.php#L81
  3. Next extension (InjectExtension) want to service by class in beforeCompile https://github.com/nette/di/blob/master/src/DI/Extensions/InjectExtension.php#L126 (btw. see second param which missing)
  4. there is null https://github.com/nette/di/blob/master/src/DI/ContainerBuilder.php#L210

testcase:

$builder = new DI\ContainerBuilder;

$builder->addDefinition('one')
    ->setClass('stdClass');

$builder->prepareClassList();

$builder->removeDefinition('one');
$builder->addDefinition('one')
    ->setClass('stdClass');

Assert::count(1, $builder->findByType('stdClass')); // Failed: Count 0 should be 1
Assert::same('one', $builder->getByType('stdClass')); // Failed: NULL should be 'one'

DI\Container::initialize(): usage of undefined $service variable

There is a bug if I add a panel into config:

nette:
    debugger:
        bar:
            - Panel

and the Panel has dependency on some service that is defined in this notation:

services:
    -
        class: MyService

It will trigger a notice about usage of undefined variable $service:

di-initialize-tracy-bar-problem

If the service is defined as:

services:
    - MyService

than everything is ok.

You can try it yourself in my sandbox branch with one commit added onto last 2.3.1 version:

VladaHejda/sandbox@b459baa

Possibility to register core DIC extension before other extensions

  • bug report? no
  • feature request? yes
  • version: 3.0.0

Description

In v3.0.0-alpha1 there is final class ExtensionsExtension which is huge BC break for extensions replacing ExtensionsExtension. This cannot be easy workarounded. I tried to solve this issue in PR #142 but I understand that it's just another workaround and proper solution is needed.

@dg talked about prioritization of DIC extensions. I don't have idea what are the plans here but this should be (I wish) solved before stable release otherwise it's not possible to upgade uprojects with custom ExtensionsExtension.

Example of extension relying on this feature: adeira/compiler-extension

Thank you very much.

CompilerExtension::validateConfig - only first level is validated

  • bug report? yes
  • feature request? yes

Description

nonExistingFirstLevel throws exception, nonExistingSecondLevel not

exampleModule:
    routeLists:
        admin:
            disabled: false
        restApi:
            disabled: true
        nonExistingSecondLevel: true
    nonExistingFirstLevel: true
$this->config = $this->validateConfig(
    $this->defaults, $this->config
);

Inject extension is not called as last extension

In Nette\DI\Compiler::processExtensions() (https://github.com/nette/di/blob/master/src/DI/Compiler.php#L159) is InjectExtension moved to end of list of extension.

If any extension is later added by ExtensionsExtension, then new extension is added after InjectExtension. This means, that any services added in extension in beforeCompile() can't take advantage of InjectExtension.

I believe, that line 159 (moving InjectExtension to end of extensions) should be after calling ExtensionsExtension::loadConfiguration() to line 168.

DependencyChecker does not works with FileMock

I have had this code in my tests. It is failing with 2.4.0.

$loader = new ContainerLoader(TEMP_DIR);
$className = $loader->load(function (Compiler $compiler) {
    $compiler->loadConfig(FileMock::create('', 'neon'));
}, 'container');

Nette\InvalidStateException: Unexpected dependency boolean

I think its cause:

// Compiler.php

/**
 * Adds new configuration from file.
 * @return self
 */
public function loadConfig($file)
{
    $loader = new Config\Loader;
    $this->addConfig($loader->load($file));
    $this->dependencies->add($loader->getDependencies());
    return $this;
}
// Loader.php

/**
 * Reads configuration from file.
 * @param  string  file name
 * @param  string  optional section to load
 * @return array
 */
public function load($file, $section = NULL)
{
    if (!is_file($file) || !is_readable($file)) {
        throw new Nette\FileNotFoundException("File '$file' is missing or is not readable.");
    }
    $this->dependencies[] = realpath($file);
       ....
}

realpath(FileMock) == bool(FALSE)


It is maybe issue in nette/tester, but I'm not sure if it is issue at all. What do you think?

Calling removeDefinition not affect list of classes

class MyExtension extends CompilerExtension
{
    function loadConfiguration()
    {
        $builder->addDefinition($this->prefix('myClass'))
            ->setFactory('My\Class');
        $builder->removeDefinition($this->prefix('myClass'));
        $builder->findByType('My\Class');
    }
}

This returning unexpected notice E_NOTICE: Undefined index: my.myClass when calling $builder->findByType('My\Class') in ContainerBuilder on line (220).

Unable to overwrite service arguments

Following configuration will merge arguments instead of overwriting them and I could not find any way to remove old arguments ($foo) or solve it differently than defining the services without using arguments. Is there any way to do it? Or maybe overwriting arguments would be better than merging (when I change class), what do you think?

# global.neon
services:
    a:
        class: Foo
        arguments:
            foo: value1
# local.neon
services:
    a:
        class: Bar
        arguments:
            bar: value2
class Foo {
    public function __construct($foo) {}
}
class Bar {
    public function __construct($bar) {}
}

$configurator = new \Nette\Configurator();
$configurator->setTempDirectory(__DIR__ . '/temp');
$configurator->addConfig(__DIR__ . '/global.neon');
$configurator->addConfig(__DIR__ . '/local.neon');
$container = $configurator->createContainer();

$container->getService('a'); // Unable to pass specified arguments to Bar::__construct()

Inheriting service from extension is not working

When I want to inherite some service from added extension (myService < extensionName.service:) I get notice Undefined index: extensionName.service. The notice origin from Compiler.php:172. I was able to figure out that problem is either in Compiler.php:processServices method (wrong parameters passed to parseServices method) or in Compiler.php: parseServices method where services and factories are merged.

I'm using the latest dev of Nette.

Overriding service definition with factory always requires return annotation

After migrating to 2.3, following behaviour changed (and I don't know if it is intentional, so I'm reporting it):

# config.neon:
services:
    someService:
        class: Some\Class

# config.local.neon:
services:
    someService:
        factory: SomeFactory::create # doesn't have @return phpdoc

Newly in 2.3 it raises User Notice: Type of service 'someService' is unknown. because it requires the @return phpdoc annotation in the factory. This worked without it in 2.2.

Config\Loader cannot be configured

While digging through config loading, I noticed that Loader cannot be configured in any way, because it is created in Compiler here https://github.com/nette/di/blob/master/src/DI/Compiler.php#L87.

The question is, how would we fix this? If one would like to provide his own instance of Loader (and for example add like some kind of YAML adapter), it would probably have to be set in Configurator and bubble from there, which is kind of a long path that it has to take to actually do something..

Factory with magic method

Currently, it is not possible to define service factory as call of magic method. It throws Factory 'Aws\Sdk::createSqs' used in service '237' is not callable. It's because this checks

try {
$reflection = Nette\Utils\Callback::toReflection($entity[0] === '' ? $entity[1] : $entity);
$refClass = $reflection instanceof \ReflectionMethod ? $reflection->getDeclaringClass() : NULL;
} catch (\ReflectionException $e) {
}
if (isset($e) || ($refClass && (!$reflection->isPublic()
|| ($refClass->isTrait() && !$reflection->isStatic())
))) {
$name = array_slice(array_keys($recursive), -1);
throw new ServiceCreationException(sprintf("Factory '%s' used in service '%s' is not callable.", Nette\Utils\Callback::toString($entity), $name[0]));
}
throws ReflectionException: Method Aws\Sdk::createSqs() does not exist. See Sdk class definition.

I would like to create client services for particular AWS services. It's much cleaner to inject client directly, than injecting Sdk and then creating a client in the class.

services:
    - Aws\Sdk({
        credentials: {
            key: %aws.access%,
            secret: %aws.secret%,
        },
        version: latest,
        region: 'eu-west-1',
    })
    -
        class: Aws\Sqs\SqsClient
        factory: @Aws\Sdk::createSqs

Multiple services from generated factory

Is it possible to generate multiple services from a single generated factory?

I've got several similar services with additional dependencies given at runtime (Strategy pattern) and I'd like to avoid writing my own factory class and repeat myself so many times when changing a single dependency as well as i'd like to avoid writing multiple single generated factories (I'm talking about ten up to twenty services / strategies, that means up to 20 factories).

Is this possible? Is it a good idea or not? What do you think?

Rough start

Hi guys,

I'm having a rough start with nette/di. I'm trying to replace the PHP parser of ApiGen by nikic's and I'm already stuck with nette/di service definition:

https://github.com/ApiGen/ApiGen/blob/master/src/Parser/DI/ParserExtension.php#L28

I would expect to be able to define the service as follows:

$builder->addDefinition($this->prefix('broker'))
            ->setFactory(function() {
                return (new ParserFactory)->create(ParserFactory::PREFER_PHP7)
            });

Alas, this throws a InvalidArgumentException. I read the following docs, but found nothing involving closures for addDefinition, its often a class name and some arguments:

Please help :'(

DI\ContainerBuilder [2.3.13] - problem with php-generator

  • bug report? yes
  • feature request? no
  • version: 2.3.13

Description

I'm getting error in nette/di:2.3.13 container generation.

Steps To Reproduce

Composer: nette/di: ~2.3.0

Exception:

   ArgumentCountError: Too few arguments to function Nette\PhpGenerator\Parameter::__construct(), 0 passed in "vendor/nette/di/src/DI/ContainerBuilder.php" on line 672 and exactly 1 expected

Stacktrace:

   in PhpGenerator/Traits/NameAware.php(25) 
   in src/DI/ContainerBuilder.php(672) Nette\PhpGenerator\Parameter->__construct()
   in src/DI/ContainerBuilder.php(580) Nette\DI\ContainerBuilder->convertParameters()
   in src/DI/Compiler.php(231) Nette\DI\ContainerBuilder->generateClasses()
   in src/DI/Compiler.php(152) Nette\DI\Compiler->generateCode()
   in src/DI/ContainerLoader.php(115) Nette\DI\Compiler->compile()
   in src/DI/ContainerLoader.php(79) Nette\DI\ContainerLoader->generate()
   in src/DI/ContainerLoader.php(44) Nette\DI\ContainerLoader->loadFile()
   in tests/cases/Compare.phpt(37) Nette\DI\ContainerLoader->load()

2.3 bc breaks

Can't believe that nobody has complained yet. I'm trying to run my OrmExtension. I'm not sure if I understand the problem correctly, but I think there are 2 issues/BC breaks.:

https://github.com/nextras/orm/blob/fe20359d7b557d83157d4a71d610e21a36c574f1/src/Bridge/NetteDI/OrmExtension.php

  • Inject extension is basically added too early, so it can inject services, which are not there yet. I'm adding services in beforeCompile method. Maybe I'm doing it wrong, but loadConfiguration method doesn't seem to be the right one for adding services.
  • Inject extension works without resolved class names, so even if I add InjectionExtension after the OrmExtension, it doesn't work, because one more $this->builder->prepareClassList(); call is needed.

Incorrectly instantiated DateTimes

I attempted to use DateTime as parameter value in my config:

parameters:
    date: 2016-09-01
php:
    date.timezone: Europe/Prague

The parameter date is instanciated (that's cool), however this is done in the PHP default time zone which is (for example) UTC whereas I explicitly specify that I want to use Europe/Prague.

From brief look inside the source codes I understand that the sections are processed separetly, however this behaviour is highly unexpected and I would consider it a pitfall as it the bugs caused are not easy to find.

ContainerBuilder - Collector feature, Modular<Filters|Routes>, Commands, EventSubscribers...

  • bug report? no
  • feature request? yes

This should make CompilerExtension more usable.

Examples of current usage in Extension

This is how it's done now. Bellow is suggestion how to do it better.

Issue: add services that implement certain interface to one collecting service

Current solution is by tag, which has few disadvantages:

  • bothers user to remember the tag, even the class is already specific (by interface it implements or class it extends)
  • polutes config
services:
    - 
        class: SomeCommand
        tags: "console.command"

instead of

services:
    - SomeCommand
  • has origin in times of named services when duplicated info, context and service locator, was normal to use

Better solution

Based on new getDefinitionByType() method (#137) and findByType() I suggest adding following method to ContainerBuilder class:

(Feel free to improve the naming.)

public function setToCollectorByType(string $collectorClass, string $collectedClass, string $setterMethod) : void
{
    $containerBuilder = $this->getContainerBuilder();

    $collectorDefinition = $containerBuilder->getDefinitionByType($mediatorClass);
    $collectedDefinitions = $containerBuilder->findByType($collectedClass)    

    foreach ($collectedDefinition as $name => $definition) {
        $collectorDefinition->addSetup($setterMethod, ['@' . $name]);
    }
}

Before

use Nette\DI\CompilerExtension;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;

class MyExtension extends CompilerExtension
{
    public function beforeCompile()
    {
        $containerBuilder = $this->getContainerBuilder();
    
        $consoleApplication = $containerBuilder->getDefinitionByType(Application::class);
        foreach ($containerBuilder->findByType(Command::class) as $name => $definition) {
            $consoleApplication->addSetup('add', ['@' . $name]);
        }
}

After

use Nette\DI\CompilerExtension;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;

class MyExtension extends CompilerExtension
{
    public function beforeCompile()
    {
        $this->setToCollectorByType(Application::class, Command::class, 'set);
    }
}

This would simplify so many use cases and encourage this architecture pattern.

What do you think?

Support for PSR-11 container interop

  • bug report? no
  • feature request? yes

Description

There is PSR-11 for DI containers that aims to bring interoperability between different DI containers. PSR itself is simple and support in Nette DI would make interop with components from different frameworks easier and wouldn't bring any BC breaks.

There are already several frameworks with PSR-11 support - ZF, Symfony, ...

I can prepare PR if needed.

Lazy load interface definitions for generated factories

Currently calling $configurator->loadContainer() triggers autoloading for all interfaces implemented by generated factories (which because of parameter and return types cause loading their dependencies…)

The solution is to either move implementation of generated factories to different file or to move it to runtime (possible utilizing anonymous classes in PHP 7)

/**
 * @return App\Components\MyComponent
 */
public function createService__248()
{
    return new class($this) implements App\Components\IMyComponentFactory
    {
        private $container;


        public function __construct(Container_7bc42fd40e $container)
        {
            $this->container = $container;
        }


        public function create(): App\Components\MyComponent
        {
            return new App\Components\MyComponent();
        }
    };
}

Return annotation containing $this confuses ContainerBuilder

I have a project that is using @return $this annotations instead of @return self, and such classes cannot be registered as services. The class resolving fails with following:

Nette\DI\ServiceCreationException
Type Mautic\Auth$this used in service 'mauticApi' not found or is not class or interface.

You can see the file in question directly here. I think return $this is not according to the phpDoc spec, but nevertheless I think ContainerBuilder should support it.

findByType not work properly

Example is more than text, so:

IMy:

interface IMy {

    /**
     * @return My
     */
    public function create();

}

My:

class My implements IMyInterface {

}

IMyInterface:

interface IMyInterface {}

Extension:

class Extension extends CompilerExtension {

    public function beforeCompiler() {
          $this->getContainerBuilder()->findByType('IMyInterface'); // Cannot find class 'My'
    }

}

If I changed IMy to:

class IMy extends IMyInterface { //... }

Now can builder find class 'My'

Question: It´s correct behavior?

DependencyChecker tries to load a class that should not be loaded

It's probably best to show this on the real case:

  • Kdyby\Events\EventsManager::setPanel() needs argument of Kdyby\Events\Diagnostics\Panel
  • Kdyby\Events\Diagnostics\Panel implements Tracy\IBarPanel
  • kdyby/events has tracy/tracy as an optional dependency
  • => Tracy\IBarPanel may not exist
  • but that does not matter because Kdyby\Events\Diagnostics\Panel is never loaded at all

The problem is that DependencyChecker is still trying to load the Kdyby\Events\Diagnostics\Panel class:

  • DependencyChecker::calculateHash() iterates over all public methods of Kdyby\Events\EventsManager which of course includes the setPanel method
  • calculateHash calls DependencyChecker::hashParameters() which iterates over all parameters of the setPanel() method (which is only the panel parameters).
  • hashParameters calls PhpReflection::getParameterType($param)
  • getParameterType calls) $param->getClass()
  • that will try to autoload the Kdyby\Events\Diagnostics\Panel class
  • which of course fail with Fatal error: Interface 'Tracy\IBarPanel' not found
  • (no ReflectionException to catch, just fatal error)

Decorator && generated factories

DecoratorExtension cannot handle types returned by generated factories.
e.g.

services:
    - {implement: FooFactoryCreatingFooControlExtendingBaseControl}
decorator:
    BaseControl:
        inject: true

Autowiring fails when using type hint in method

I have something like this:

namespace App\Forms;
use App\Model\Item;

interface IFormFactory
{
    /**
     * @param Item 
     * @return Form
     */
    function create($item);
}

And this works. But when i add type hint into method param like this:

namespace App\Forms;
use App\Model\Item;

interface IFormFactory
{
    /**
     * @return Form
     */
    function create(Item $item);
}

Autowiring fails because generated Container looks like this:

public function create($item) {
....
}

and function create isn't same as it has been declared in interface.

Better API for ContainerBuilder::findByType

ContainerBuilder::findByType and Container::findByType works similar:

  • returns names of services (because Container cannot return objects)
  • by default they return only autowired services

On the one hand it is good that these two functions behave consistently, but on the other hand, it is uncomfortable to use ContainerBuilder::findByType:

  • you can always need retrieve definition using $builder->getDefinition($name)
  • it's not clear what FALSE means (classic boolean arguments problem)

So I think that ContainerBuilder::findByType should return all services as pairs [name => definition].

The question is whether Container::findByType can be in future changed to return names of all (including non-autowired) services too? Is it big BC?

(ContainerBuilder::findByType and second argument of Container::findByType exist only in dev-version).

Unreliable setup ServiceDefinition of generated factory

The following code may or or may not work at all depending on whether the service implementation is generated by Nette DI.

$serviceName = $builder->getByType(Nette\Bridges\ApplicationLatte\ILatteFactory::class);
$serviceDef = $builder->getDefinition($serviceName);

// this may configure either ILatteFactory or Latte\Engine instance
$serviceDef->addSetup('addFilter', ...);

I think that the current behavior is highly confusing. Service definition of the implementation should use different instance (e.g. $serviceDef->getInstanceDef()->addSetup('addFilter', ...)).

When the factory implementation is not generated by Nette DI, modifying of the definition of instance service definition should ideally generate another implementation which would wrap the user provided implementation.

cc @matej21

Changed service causes dependency checks on every request

There is a problem with current DIC expiration check.

Cosider following config:

services:
- MyService

Let's say I change content of MyService.php from

<?php
class MyService {}

to

<?php
class MyService
{
    public function foo();
}

(file changed, dependencies didn't)

On next request DependencyChecker compares modification times with meta file of generated container, which differs. Dependency hash is now calculated and matches the one in meta file, so container is considered non-expired.

The problem is that meta file is not updated and hash is calculated on every request, which leads to performance overhead for large containers.

Support for ENV variables

Syntax could leverage support for arrays a: %env.NAME% with all variables in %env%.

Things to consider:

  • Syntax for default values.
  • Whitelist by default.
  • Invalidate cache if used ENV has changed.
  • Interface to access them in extensions. (to complement config and add requested ENVs to whitelist)

I have created extension to add partial support for ENV variables. It has whitelist and default values and partial support for configs. Cache invalidation is not implemented

Parameters auto-resolution for generated factories depends on variable name

Following example:

services:
    - ISomeControlFactory
interface ISomeControlFactory {
    /** @return SomeControl */
    public function create(SomeEntity $someEntity);
}

class SomeControl {
    public function __construct(SomeEntity $entity) {}
}

class SomeEntity {}

leads to exception

Service 'XX_ISomeControlFactory': Service of type SomeEntity needed by SomeControl::__construct() not found. Did you register it in configuration file?

just because the parameter variables have different names.

Add getDefinitionByType() method

While making extension, I often need some service definition in beforeCompile() method, e.g.:

After making service name optional, this is the only place where it is still required.

Everywhere I need some definition, I have to use these 2 methods:

$containerBuilder = $this->getContainerBuilder();
$serviceName = $containerBuilder->getByType(Nette\Bridges\ApplicationLatte\ILatteFactory::class);
$serviceDefinition = $containerBuilder->getDefinition($serviceName);

I would prefer having single method:

$serviceDefinition = $containerBuilder->getDefinitionByType(
    Nette\Bridges\ApplicationLatte\ILatteFactory::class
);

What do you think?

Incompatibility with neon

nette/di dev-master doesn't work with nette/neon 2.2 (it should according to composer.json). It fails with this error:

`Fatal Error
Undefined class constant 'CHAIN'

File: vendor\nette\di\src\DI\Config\Adapters\NeonAdapter.php:63

why di config/loader parsed result is not compatible to neon format?

I am improved the config class with neon, now it can be write like this:

services:
    - App\Play\Provider
    - App\Play\Sender
    - App\Play\Logger(dev.log)

prod < services:
    - App\Play\Logger(prod.log)

test < services:
    - App\Play\Logger(test.log)

it can merge config in every env, I'd like it :-P

but when I try to use addConfig() method to set di config to compiler, it was error, because Nette\Neon\Entity is not Nette\DI\Statement

could you make they to be same class? or compatible neon entity in Validator?

Broken creation of services that have optional array constructor dependency

if you have a class with constructor like this

public function __construct(array $server = array(), History $history = null, CookieJar $cookieJar = null)
{
    $this->setServerParameters($server);
    $this->history = $history ?: new History();
    $this->cookieJar = $cookieJar ?: new CookieJar();
}

and config.neon

- Goutte\Client

this exception is raised exception 'Nette\DI\ServiceCreationException' with message 'Class array needed by Symfony\Component\BrowserKit\Client::__construct() not found. Check type hint and 'use' statements.'

this class is just an example, it happens with all array typehints. it started to happen in recent versions of nette

before it worked just fine

BC Break in ServiceDefinition (SmartObject)

Introduced in 69b056e, related #106

It would be nice if somebody could fix this BC break - since this is pretty hard deprecation (while there is no reason for it) and it would be nice to have some transition time with soft-deprecation.
Yaay for removing magic, booo for BC Breaks :)

I may do it myself, but I would preffer if somebody else did it - since I have very little free time right now
Thanks.

New parameter %rootDir%

One of the very few things that prevents Nette application from beeing compiled before deployment (and therefore using it on readonly filesystems) are hardcoded absolute paths in DI Container.

Now imagine if you were to tell the container the root directory of the project.

// this ofcourse could be autoresolved by default, but the setter should be available
$configurator->setRootDir(dirname(__DIR__)); //  dirname(%appDir%)

Now that we have the absolute path, we can set the value "dynamically"

class SystemContainer
{
    public function __construct()
    {
        parent::__construct(array(
            // ....
            'rootDir' => __DIR__ . '/../..',
        ));
    }
}

and the strings in generated container that contain the rootDir string can be replaced with the dynamic value

"/var/www/hosts/kdyby.org/app/../www/images"
$this->parameters['rootDir'] . "/app/../www/images"

This is merely a concept and there are other obstacles, but IMHO this is the main one. Composer uses the same concept for the generated autoloader. I think we should do it similarly.

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.