Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
110 lines (67 sloc) 2.83 KB

Quickstart

The best way to install Kdyby/Autowired is using Composer:

$ composer require kdyby/autowired

Include in application

Package contains two traits that you can include in your PresenterComponents.

The first one is just for properties and the second one is for component factories.

abstract class BasePresenter extends Nette\Application\UI\Presenter
{
	use Kdyby\Autowired\AutowireProperties;
	use Kdyby\Autowired\AutowireComponentFactories;

	// ...
}

For debugging purposes you may also add the AutowiredExtension in config, which registers Tracy panel

extensions:
	autowired: Kdyby\Autowired\DI\AutowiredExtension

Autowired properties

Every protected or public property marked with @autowire annotation will be under control of AutowireProperties trait, we will call them "autowired properties".

The properties are analysed and result of the analysis is cached. This means, that you will see errors in your configuration instantly, and not after you use it in some conditional code, that might not even be executed every time. This is here to help you find errors, as early as possible.

Every autowired property will be unsetted, when presenter is created, and then the trait takes over using __get() and __set() magic. The service will be created only if it's really used and it cannot be overwritten, once it has some value.

This behaviour is inspired by article DI and property injection by David Grudl.

class ArticlePresenter extends BasePresenter
{

	/**
	 * @autowire
	 * @var App\ArticleRepository
	 */
	protected $articleRepository;

	/**
	 * @var Kdyby\Doctrine\EntityDao
	 * @autowire(MyApp\Blog\Article, factory=\Kdyby\Doctrine\EntityDaoFactory)
	 */
	protected $factoryResult;

	// ..

}

Autowired component factories

There is often needed to inject a component factory object to the presenter and then use it in lazy component factory method that connects the created component to the component tree.

What if the component factory object from DI Container could be passed directly to the component factory method, without all that boilerplate code?

class ArticlePresenter extends BasePresenter
{

	// ..

	/**
	 * @return My\Awesome\Datagrid
	 */
	protected function createComponentDatagrid($name, IDatagridFactory $factory)
	{
		return $factory->create();
	}

}

The $name parameter can be omitted, createComponentDatagrid(IDatagridFactory $factory) works as well.

Cool right?

Not so clean...

Just keep in mind, that is not a clean approach - it's pragmatic. Never try to use these traits in model classes. Strictly use constructor injection whenever it's possible!

You can’t perform that action at this time.