-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce Dependency Injection #4917
Comments
Here is a sum up of our discussion: Migration from Singletons to DIStep 1
Quick and dirty example: // This is the old Singleton
// It's now just a facade/proxy
class Db
{
public static function get()
{
if (self::$connection === null) {
// Create the DB object
}
return self::$connection;
}
public static function fetchAll(...)
{
// Forward to the real object
self::get()->fetchAll(...);
}
}
// This is the new object
class Database
{
private $connection;
public function __construct(DbConnection $connection)
{
$this->connection = $connection;
}
public function fetchAll(...)
{
// Do the real stuff
}
} What's cool:
Step 2
Step 3Slow migration from using singletons to injecting dependencies:
Step 4In some future version we can remove the singletons. Architecture of pluginsWe have 2 options: We discussed both options, and kind of agreed that it's OK if plugins can override Core config. It should be recommended that plugins shouldn't do it, but leaving the door open to that can be very useful in some situations. It will be the plugins responsibility to make the right choice. So in the end one container + several config files is the simplest option. It is also the solution is used by Symfony in its system of Bundles, and it's very powerful. Here is for example how configs could be included:
The latest included config can override the previous ones. That way plugins can enrich, or override the default config, and then the user can always re-override everything. Here is an example with Authentication:
In the plugin's config file, there is the configuration for
Then everywhere we want to use Auth, we inject EventsRegarding the events, and the fact that "Components" have to extend the interface (so that events are auto-declared), we are not all on the same page. Since this is not needed right now, we can come to a decision later on. ContainerWe have discussed several options, we agree that having autowiring and annotations would be great (like in Spring), we have discussed maybe using PHP-DI (which covers that). The question is still open (I think obviously PHP-DI would fit the bill pretty nicely but I'm not objective :p). Here are some documentation topics that are related if you want to learn more:
And if you have any question about it just ask |
+1 for DI in Piwik |
Hi all, here are the 2 POC we discussed for the steps described above:
|
Requirement #2 (and the whole event dispatching system) can be removed if DI solution makes it easy for plugins to composit existing components. For example, a plugin could create a new Auth component that composits (ie, uses) the existing injected component. The compositing object can manipulate the existing component w/o having to use events, and the problem w/ plugins & event ordering can be avoided too. |
👍 |
If possible I think replacing INI config w/ DI config would be a good idea. Ie move all settings in INI config to DI config while still keeping it easy for end users to modify. |
fyi we must keep INI format because we don't want to update all FAQs and guides explaining how to change settings etc. |
We can keep it backwards compatible or still support INI, but DI config will be much more powerful since you should be able to configure actual objects. For example, it should be possible (w/ correct Piwik architecture), to create a DAO object that uses a NoSQL solution and associate it w/ the selecting/aggregating (ie, map/reduce) logic, create DAO objects that use MySQL for sites, users and other relational data and create a DAO object that uses a key/value store for archive data all in a config file. It would be very hard and very ugly to represent such a configuration using only INI config and plugin event observers. |
…th Dependency injection refs matomo-org#4917
Heya @mnapoli, |
Let's close it, it's been long out of date. |
For anyone interested about using Dependency Injection in Piwik see this guide: https://github.com/piwik/developer-documentation/pull/67/files?short_path=762e172#diff-762e172d280769ca6701a87863ec30f2 |
@mnapoli I have two questions:
|
Not sure about our official point of view with the deprecated class StaticContainer @diosmosis what do you suggest, maybe the class is not deprecated after all, since we still use it in few places?
yes, you can create DI config.php files in plugins, see for example https://github.com/piwik/piwik/blob/master/plugins/Diagnostics/config/config.php |
Thanks @mattab ! What is the order of including of such config files ? Can I override some service/class that is already defined in the main config from a plugin ? |
Yes, plugins DI config should override core DI config. |
It will be removed in 3.0. It has to be used now because Piwik dependencies are too tangled up, and because of |
Here are already some requirements I got from some core developers:
re 2) I think it is not directly related to this feature.
I think we do not need to have all features in the beginning. For instance we can implement 6) later on top of DI.
Next step:
Do we have more requirements? Do we maybe not need any of those requirements? Does anyone can recommend any good library to fulfill our needs or can someone recommend any lib in general?
Then:
We could start refactoring two or three components to use DI. For instance Log, Access and Config?
A problem might be backwards compatibility as current plugins access those instances via Singleton.
The text was updated successfully, but these errors were encountered: