Los métodos de concentrador SignalR intentan resolver los parámetros a partir de la inserción de dependencias

Los métodos de concentrador SignalR ahora admiten la inserción de servicios desde el contenedor de inserción de dependencias (DI). En casos aislados, esto puede interrumpir las aplicaciones que tienen un tipo en la DI que también se acepta en los métodos de concentrador de mensajes de cliente de SignalR.

Versión introducida

ASP.NET Core 7.0

Comportamiento anterior

Si aceptó un tipo en el método de concentrador que también estaba en el contenedor de inserción de dependencias, el tipo siempre se resolvería a partir de un mensaje enviado por el cliente.

Services.AddScoped<SomeCustomType>();

class MyHub : Hub
{
    // type always comes from the client, never comes from DI
    public Task Method(string text, SomeCustomType type) => Task.CompletedTask;
}

Comportamiento nuevo

Los tipos de inserción de dependencias se comprueban al iniciar la aplicación con IServiceProviderIsService a fin de determinar si un argumento de un método de concentrador procede de la inserción de dependencias o del cliente.

En el ejemplo siguiente, que supone que usa el contenedor de inserción de dependencias predeterminado, SomeCustomType procede del contenedor de DI y no del cliente. Si el cliente intenta enviar SomeCustomType, obtiene un error:

Services.AddScoped<SomeCustomType>();

class MyHub : Hub
{
    // comes from DI by default
    public Task Method(string text, SomeCustomType type) => Task.CompletedTask;
}

Tipo de cambio importante

Este cambio afecta a la compatibilidad de origen.

Motivo del cambio

Este cambio mejora la experiencia del usuario al usar diferentes servicios en distintos métodos de concentrador. También mejora el rendimiento al no requerir que el usuario inserte todas las dependencias en el constructor del concentrador.

La probabilidad de interrumpir las aplicaciones es baja, ya que no es habitual tener un tipo en DI y como argumento en el método de concentrador al mismo tiempo.

Si este cambio le interrumpe, puede deshabilitar la característica estableciendo DisableImplicitFromServicesParameters en true:

Services.AddSignalR(options =>
{
    options.DisableImplicitFromServicesParameters = true;
});

Si el cambio le interrumpe, pero quiere usar la característica sin interrumpir a los clientes, puede deshabilitar la característica como se muestra anteriormente y usar un atributo que implemente IFromServiceMetadata en nuevos argumentos o métodos de concentrador:

Services.AddScoped<SomeCustomType>();
Services.AddScoped<SomeCustomType2>();

class MyHub : Hub
{
    // old method with new feature (non-breaking), only SomeCustomType2 is resolved from DI
    public Task MethodA(string arguments, SomeCustomType type, [FromServices] SomeCustomType2 type2);

    // new method
    public Task MethodB(string arguments, [FromServices] SomeCustomType type);
}

API afectadas

Métodos de concentrador