Closed ghost closed 9 years ago
I think this is up to the developer, we don't want to be passing around the container as this is classed as bad design. If you require this for your own application, you should probably replace the Resolver inside of the Container with your own implementation.
I agree with @silentworks.
Hmmm ... Route -> Function ... container is available inside the function so it is passed inside also. How come this is not bad design ?
$app->get('/foo', function ($req, $res, $args) { $container = $this->getContainer(); $myService = $container->get('myService');
return $res;
});
Another issue is that CallableResolver is defined as Final class and can not be overwritten ... already tryed ;)
@xMolchy almost all classes in the framework can be replaced and CallableResolver is one of them. Using the service inside of a closure would almost be the only way of getting an service inside of the closure, you can't inject dependencies into an closure unless you want to write some non-performant code.
You can replace using the code below:
$container = Slim\Container();
$container['callableResolver'] = function ($c) {
return new MyOwnCallableResolver($c);
}
$app = new Slim\App($container);
To follow up, CallableResolver
is final as solely implements CallableResolverInterface
as suggested by https://ocramius.github.io/blog/when-to-declare-classes-final/
I understand why is final no issues there ... but why allow passing container into functions of the route but not the class-es ? explanation why is bad design ?
Ty for: $container['callableResolver'] = function ($c) { return new MyOwnCallableResolver($c); }
;) did not know can do that ... can i use the same for "Route" to extend some chain functions ... for example route validation also which container i wish to pass into specified routes (depands which application what needs) ?
Ty already extended personal knowledge ;)
Mainly because there's no way to inject dependencies into a closure.
Oh, and for the record, we're totally happy to have our decisions questioned.
@xMolchy its bad design because we have no idea of the requirements of each Class at that point, we are also giving the caller(Class) access to everything inside of the container even if it doesn't need them. There are also issues our IDE will have to deal with if we needed to deal with any refactoring as we would be working with strings inside of our Classes and not actual object references.
Yes you can do the same with the Router
which creates the Route.
@akrabat Ty for the information. Above information already allows me to do some custom things which are needed, but do not want to change slim core files within Slim ... normally overwrite or extend.
Discussion are always needed in any project, more minds know more ...
@silentworks I understand, it is very hard to make an framework to satisfy everyone's needs, that's why i like Slim ;) its Slim and i put needed things myself. You can not fully support object references for refactoring in IDE ... new [$class, $function] does not help ;) . My plan is to extend "Route" with chain function that i can specify which container i wish to pass into the specific route (Api, Web, Soap have different needs) and then CallableResolver change that i have access to specified container so i can do MVC/HMVC structure and perform this inside Controller classes $this->view = $container->get('view'), database, logs, ....
Ty and great work on Slim!
For example not everyone wants all classes to be in a Container, i think most people will put in the ones that are commonly used like "view", "log", "db" ...
So not everyone will want to define and pass container instance into the class: $container['Action'] = function ($container) { return new Action($container); };
What if class is autoloaded and i just wanna do: $app->get('/', 'Action:dispatch'); In this aproache without above definition container does not get avaible inside custom class ...
FILE: CallableResolver.php CHANGE: $resolved = [new $class($this->container), $method];