-
-
Notifications
You must be signed in to change notification settings - Fork 87
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
DI: Nette\Http\Request subclass is required instead of interface #90
Comments
There should be no references to Can you try to find out, what service is requesting the class? You should first check your application, to make sure you're not requiring the class itself, instead of interface and then check the extensions you're using. Also maybe upgrade Nette, since the last references were removed few versions ago. And also, the request object is a value object, that should in fact be a service. If you wanna work with multiple requests, you should use Kdyby/RequestStack. |
@fprochazka I'm using this default extension. After container was created, I tried to replace http request service with code above, and it failed with the exception. |
I remember that there was a break BC, when I changed it to interfaces, but I don't remember the details. |
@dg yes, there would be a BC break if someone requires Http\Request directly and not the interface. |
Exactly. @iinfo-dev-mk IMHO you can change option |
Require Http\Request directly isn't good practice if DIC offers service name by default. But replace particular service with another one is valid requirement for the DIC. @dg No, see the issue description, there is no issue with the configuration, I need to use removeService, addService calls. Replacing services this way doesn't work correctly. Hence I also noticed if problem isn't in DI container itself, see my description. |
I mean that you can IMHO change class in config.neon
and then replace it in bootstrap. DI container behaves correctly. |
Again, no, I can't use any config file, there is only PHP code which wants to replace service in already built DIC ($context variable) ''dynamically'' via $context->removeService("http.request");
$context->addService("http.request", new OwnRequest()) It worked fine with nette 2.2 and fails with the exception in nette 2.3. Again, problem can be in DIC itself, when I call removeService(serviceName) I expect that DIC removes all information about particular service, but it seems that isn't true. |
So change it via Dynamic changes in container are limited, because it is statically compiled, so you cannot change one class to another when they are not descendants. |
I can't call any $configurator, PHP code knows only about already built DIC, which is passed in. If DIC can't dynamically replace service with instance of same interface such DIC is useless. Generally PHP is dynamic language, types are complete optional, any object can be passed as argument to any function and fails only in runtime if user want. So there is no reason to limit add, remove or replace services in DIC dynamically. |
It can. Problem is that there is, for a compatibility, concrete class instead of the interface. Why can't you modify config? If you are using IRequest everywhere, it won't break anything and you will be able to replace the service dynamically. |
@matej21 Our code with dynamic modification of DIC is used in special internal testing case from command line and only for that purpose there is necessary to replace default http request with special one, which is created also dynamically according command line arguments. I know that dynamic changing of DIC is the edge case, but shouldn't be limited to even interfaces. It's very handy to use some small piece of dynamic PHP code for such special situations, without modification of application itself, we are in PHP not in Java. |
@iinfo-dev-mk Noone argue, that DIC should allow to replace interface instance by another one. You are right. And DIC works in this way. But If class OwnRequest2RequestWrapper extends Http\Request
{
private $own;
public function __construct(OwnRequest $own)
{
$this->own = $own;
}
# here overload all public methods to call $this->own methods
} Such class instance can replace It's not nice, it's workaround but IMHO it will work. |
Yes, it is bad, can you please send pull request to the documentation? https://github.com/nette/web-content/blob/doc-2.3/en/migration-2-3.texy (Related commit nette/di@116eb12) |
@milo Yes I know, after all I eventually finish with inheriting from Http\Request but I don't like it, because it depends on Http\Request changes in the future and I need to investigate Http\Request and OwnRequest relation, it's much more fragile then before. And still I think dynamic modifications of DIC via removeService, addService can be more relaxed, because it's primary targeted for special cases where such possibility is useful. |
@dg documentation - OK, I will try later this week |
This BC break can be probably solved via narrowed autowiring in DI 2.4 and alias. |
Fix reverted, solution is here #90 (comment) |
When we want to you own service for http request, subclass of Nette\Http\Request is required
it throws exception
Nette\InvalidArgumentException: Service 'http.request' must be instance of Nette\Http\Request, OwnRequest given
I think same problem is with all services from Nette\Http package. Only interface can be requested, not class.
Maybe problem is with DI container itself, when removeService is called, I wan't to remove all information about particular service, it seems that in DI container still remains some information about removed service, what isn't desirable.
The text was updated successfully, but these errors were encountered: