Open dotnetjunkie opened 3 years ago
Thanks for contacting us. @davidfowl please let us know what needs to happen here.
Thanks for contacting us.
We're moving this issue to the Next sprint planning
milestone for future evaluation / consideration. We will evaluate the request when we are planning the work for the next milestone. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
After a previous discussion (https://github.com/dotnet/aspnetcore/issues/8886), the
IComponentActivator
abstraction was introduced in .NET 5 (#19642). Unfortunately, implementations of this new abstraction are not expected to apply any injection, as the documentation forIComponentActivator
states:Instead, the "responsibility for dependency injection", i.e. property injection, is implemented in the
ComponentFactory
class. The implementation of property injection, however, is hard coded to use theIServiceProvider
abstraction. There is no way to intercept this behavior andComponentFactory
is internal with no option to replace it.This, unfortunately, makes the given
IComponentActivator
abstraction useless from a DI perspective (as proposed in #8886). While non-conforming containers would like to intercept the composition of object graphs of Blazor components (including the composition of all their dependencies), they can only intercept the creation of the Blazor component itself; not the injection of its dependencies, becauseComponentFactory
is responsible for this. A non-conforming container, however, does not replace the built-in container, and whenComponentFactory
callsIServiceProvider
, it requests the dependency from the built-in container, not from the non-conforming container. As such dependency would not be part of the built-in container,ComponentFactory
will throw the following exception:To work around this situation, users of a non-conforming container would have to:
@inject
attribute, as this is hard-wired to the built-inIServiceProvider
abstraction. This could be achieved by defining properties inside the@code
tag, using a custom attribute that marks the property for DI.InjectAttribute
can't be used, becauseComponentFactory
reacts to that.Neither of the two options above are practical or desirable and we should try to improve integration to make this possible.
I see two possible solutions:
ComponentFactory
intoDefaultComponentActivator
and makeDefaultComponentActivator
public. This allows replacing property injection behavior by interceptingIComponentActivator
. By makingDefaultComponentActivator
public, a customIComponentActivator
implementation can forward the call to the default implementation for framework components, which is important because it will be responsible for doing property injection on framework components.IComponentInitializer
abstraction could have avoid Initialize(IComponent)
method that applies property injection where the framework'sDefaultComponentInitializer
would get injection logic and caching that is currently part ofComponentFactory
.Both options have their pros and cons:
Logger<MyBlazorComponent>
into anILogger
property on a type calledMyBlazorComponent
. This is a scenario that's easy to miss because the built-in container lacks this ability, while it is often an important feature of many mature DI containers. Keeping construction in this single call, however, benefits conforming containers (like Autofac) as well, because it might allow them to apply contextual property injection as well.IComponentActivator
contract, which is expected to be "not responsible for dependency injection." This is a breaking change.Perhaps there are other options to consider. If you think there are, please post your ideas below.
/cc @davidfowl