Skip to content
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

Allow custom component instantiation #7962

Closed
CatoLeanTruetschel opened this issue Feb 26, 2019 · 10 comments · Fixed by #23607
Closed

Allow custom component instantiation #7962

CatoLeanTruetschel opened this issue Feb 26, 2019 · 10 comments · Fixed by #23607
Labels
area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one

Comments

@CatoLeanTruetschel
Copy link

CatoLeanTruetschel commented Feb 26, 2019

Change the access modifier of ComponentFactory to public to allow instatiation of components.

An even better solution is to add an interface IComponentFactory that is implemented by ComponentFactory and that is registered in the ServiceCollection.

My current use case for this:
I implemented a system to split a blazor/razor-components project into multiple modules that are loaded lazily. The modules define view-extensions that can be rendered whereever needed. The view-extension rendering engines does not know about the concrete type of the component at compile time but needs to instantiate a component (of a type that is known at runtime), configure it with some values and finally render it. Currently I need to copy the source of ComponentFactory to my project to allow this.

If you like, I can implement this and open a PR for it.

@Eilon Eilon added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Feb 26, 2019
@mkArtakMSFT mkArtakMSFT added the area-blazor Includes: Blazor, Razor Components label Mar 25, 2019
@mkArtakMSFT
Copy link
Member

We've moved this issue to the Backlog milestone. This means that it is not going to happen for the coming release. We will reassess the backlog following the current release and consider this item at that time. However, keep in mind that there are many other high priority features with which it will be competing for resources.

@mkArtakMSFT mkArtakMSFT added this to the Backlog milestone Apr 3, 2019
@mkArtakMSFT mkArtakMSFT added the enhancement This issue represents an ask for new feature or an enhancement to an existing one label Apr 3, 2019
@mkArtakMSFT mkArtakMSFT removed area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates labels May 9, 2019
@stsrki
Copy link
Contributor

stsrki commented Jul 28, 2019

I would also like this feature to be implemented as it would allow me to easier instantiate custom components. The PR as I can see is fairly straightforward so is there a reason why it's not already merged?

@mkArtakMSFT
Copy link
Member

Thanks for your PR, @AndreasTruetschel. We still need to think through this. Looking into your workaround, it seems completely reasonable and is what we would recommend. So for now, we're closing your PR till we get a better idea about the direction we would like to take this.

@jspuij
Copy link
Contributor

jspuij commented Jan 27, 2020

@mkArtakMSFT So the workaround is to compile your own version of Blazor? You cannot be serious about that. It is mindboggling that microsoft forces DI upon everyone through the asp.net core framework, yet do not use the same DI container for Component creation with the argument that the framework needs to be in control of component creation. Yet we DO get parameter injection, which makes even less sense.

Allow us to use the container to instantiate components or provide a good argument why the container should not be allowed to be used to instantiate components.

@XomegaNet
Copy link

I agree with @jspuij.

Is there any reason why ComponentFactory.InstantiateComponent method does not use the supplied serviceProvider to create Blazor components, and uses Activator.CreateInstance instead?

The use case we have is where a developer needs to use a custom component, but cannot specify it directly in the .razor files, since the latter are generated, and cannot be updated directly. In this case, they'd be able to register a (transient) custom subclass of that component with the DI container and have that subclass instantiated instead of the one specified in the .razor file.

Xomega.Net generates Blazor views from an XML model, with a goal to allow users to change the model and regenerate the views, so any manual changes to the views would be wiped out. At the same time, we want to allow the users to customize the default components that are used in the generated views, and dependency injection would allow them to use a custom subclass.

Also, the component authors would be able to use standard constructor dependency injection, and not just forced to get everything injected into properties with an Inject attribute, for what it's worth.

@davidfowl
Copy link
Member

cc @dotnetjunkie

@jspuij
Copy link
Contributor

jspuij commented Jul 7, 2020

Thank you! Very much appreciated.

@dotnetjunkie
Copy link

Here's a third use case that seems impossible with the current implementation: injected properties are always resolved from the built-in DI system, never from a third-party 'non-conforming' container.

To me, the solution seems simple, Blazor Components need a similar design as the rest of the system has, i.e. a factory/activator abstraction pair. This means that the internal ComponentFactory should implement a public IComponentFactory factory interface.

@jspuij
Copy link
Contributor

jspuij commented Jul 8, 2020

@dotnetjunkie When you have constructor injection available I'd completely skip property injection by attribute through the framework. However I do agree with your comment.

@dotnetjunkie
Copy link

To be honest, I'm unsure why the team decided to implement property injection, because to my knowledge non of other parts of the framework apply property injection, the built-in container does not supportnit, and property injection leads to temporal coupling.

@dotnet dotnet locked as resolved and limited conversation to collaborators Aug 7, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants