Ok I understand your approach now. However, I don’t understand the benefits of DI for views. Maybe this is getting too off topic. After thinking about it I still can’t find real benefits in DI for views. Yes you can silently replace the view helper but the advantage in better testability doesn’t really work in a view, does it?

This may allow you to adapt views of extensions without completely overriding them. For example I may have requirement that all external links in my website should have target="_blank" rel="nofollow noopener". I can create my custom helper with a() method which will do that transparently, but if some extension uses static call to Html::a() in its view, my helper will not be used. I need to override the whole view to change one Html::a() to use my helper instead of basic one. With DI I could just inject my helper to extension view and extension will use implementation I prefer.

Yep, didn’t thought about extensions… But I was not thinking in making them global, just thought it could be a core based self-dynamic way to do it on app demand, for functions and for any namespaces and so. I was really in stratospheric sci-fi here. Thanks for the answer @samdark.

I honestly believe that we should maintain the array configuration in the widgets and static helpers, I think that injecting everything through the container di would be equal to Yii2, in my opinion the views are only the representation of the result, and using static helpers would be fine, for On the other hand we would leave things like Yii2 like helpers and widgets that do not need a great design.

Html static class could be initialized first somewhere with required service, for example, BootstrapUIService, this service could use other services, for example, CoreHtmlService, InlineCssService, AssetsService. So we could easily change functionality.

Does injecting HTML helper as insatiable object to View was ever considered?
$this->html->input($bla, $bla)
or
$html->input($bla, $bla)
This could allow to switch between helper implementation without changing view itself (for example switching between TB 3 and TB 4 may require only changing HTML helper used by view component).

But in your solution exists one advantage. We can easily use another UIService for some part of appication. But @samdark proposed to use static class, thats why I did such a solution. But there is no problem to compose those approaches and give possibility to choose.

And that changes everything :D. You can have only one Html::$UIService at the time, and changing it in one place will affect any other places too. With local instances you have much more control and less unexpected side effects.

Agreed, but we can combine those aproaches. For simple projects we can use Facade, but advanced user can type more.

And I think it is, in general, a viable approach. To give 2 options in framework, easy and highly customisable. Easy way would help new people to start and the hard way gives satisfaction to users with high requirments. “Easy to get, hard to master”

If I’m writing an extension, how can I rely on this? If html helper will not be configured in default parameters at app level, then it will not be available in view - I need to inject Html instance myself to make sure that it is available. But in that case end user will not be able to overwrite this helper at app level.