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
中樞方法