Skip to content

Register Blazor's ComponentHub in the IServiceCollection #29194

Closed as not planned
@dotnetjunkie

Description

@dotnetjunkie

Some non-conforming DI Containers rely on the use of ambient state for providing scoping. This causes a challenge when it comes to integrating with with Blazor due to the way both Blazor and SignalR are set up.

Such container (such as Simple Injector) will have to replace SignalR's default IHubActivator<T> implementation in order to apply scoping. But even without ambient scoping, non-conformers will likely want to replace the IHubActivator<T> in order to resolve application hubs. When replacing IHubActivator, however, there is no way to callback into SignalR's DefaultHubActivator<T> to resolve framework hubs, such as Blazor's ComponentHub, as DefaultHubActivator<T> is internal.

Implementing a custom IHubActivator<T> likely means choosing one of the following three options:

  1. Completely reimplement DefaultHubActivator<T>'s behavior in order to resolve framework types like ComponentHub
  2. Resolve ComponentHub directly from the built-in container
  3. Resolve ComponentHub directly from the third-party (non-conforming) container

About these options:

  • Option 1 is not desirable because of the amount of code duplication it causes for integration scenarios and the possibly conflicts when the default implementation changes in the future.
  • Option 3 is difficult to achieve because ComponentHub is an internal type. Neither application code, nor a third-party can access this type and accessing using reflection is brittle as the internal type could change in the future.
  • Option 2 is currently impossible because ComponentHub is not registered in the IServiceCollection.

There are multiple possible solutions:

  • Make SignalR's DefaultHubActivator<T> public. This allows the custom activator to create or possibly inject the default activator and call it
  • Make ComponentHub public. This allows an application developer or non-conforming integration package to register it in the application container, or optionally directly into the IServiceCollection
  • Register ComponentHub into the IServiceCollection. This allows a custom activator to resolve this type from the framework container without requiring ComponentHub to become public.

I think adding ComponentHub to the IServiceCollection is the easiest solution because it doesn't require making any type public, which saves writing and maintaining new documentation. Adding ComponentHub to the IServiceCollection is likely a very low-risk operation. The risk of it breaking existing applications presumably is very low.

Metadata

Metadata

Assignees

No one assigned

    Labels

    affected-very-fewThis issue impacts very few customersarea-blazorIncludes: Blazor, Razor ComponentsenhancementThis issue represents an ask for new feature or an enhancement to an existing onefeature-blazor-serverinvestigateseverity-majorThis label is used by an internal tool

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions