SignalR Service 中樞方法試圖解析 DI 中的參數

現在 SignalR Service 中樞方法支援從相依性插入 (DI) 容器插入服務。 在極少數的案例中,這麼做會中斷在 DI 中具備型別,且該型別同時受 SignalR 用戶端訊息中中樞方法接受的應用程式。

導入的版本

ASP.NET Core 7.0

先前的行為

如果您在中樞方法中接受同時存在於相依性插入容器中的型別,則用戶端傳送的訊息一律會解析該型別。

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;
}

新的行為

DI 中的型別會在應用程式啟動時透過 IServiceProviderIsService 檢查,藉此判斷中樞方法中的引數來自 DI 或用戶端。

在下列假設您使用預設 DI 容器的範例中,SomeCustomType 來自 DI 容器而非用戶端。 如果用戶端試圖傳送 SomeCustomType,則會收到錯誤:

Services.AddScoped<SomeCustomType>();

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

中斷性變更的類型

這項變更會影響來源相容性

變更原因

這項變更能改善使用者在不同中樞方法中使用相異服務的體驗。 同時,由於不需要使用者在中樞建構函式中插入所有相依性,因此也能提升效能。

應用程式中斷的可能性不高,因為少有同時在 DI 中具備型別,且該型別在中樞方法中作為引數的狀況。

如果這項變更害您中斷,請將 DisableImplicitFromServicesParameters 設定為 true,藉此停用功能:

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

如果這項變更害您中斷,但您想在不中斷用戶端的前提下繼續使用,請依照上述方法停用功能,並使用在新的引數/中樞方法上實作 IFromServiceMetadata 的屬性:

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

中樞方法