將 gRPC 服務從 C-核心遷移至 ASP.NET CoreMigrating gRPC services from C-core to ASP.NET Core

作者:John LuoBy John Luo

由於基礎堆疊的執行,並非所有功能在以C 核心為基礎的 gRPC應用程式和 ASP.NET Core 型應用程式之間以相同的方式工作。Due to the implementation of the underlying stack, not all features work in the same way between C-core-based gRPC apps and ASP.NET Core-based apps. 本檔將重點放在兩個堆疊之間進行遷移的主要差異。This document highlights the key differences for migrating between the two stacks.

gRPC 服務實生命週期gRPC service implementation lifetime

在 ASP.NET Core 堆疊中,預設會以限定範圍的存留期來建立 gRPC 服務。In the ASP.NET Core stack, gRPC services, by default, are created with a scoped lifetime. 相反地,gRPC C-core 預設會系結至具有單一存留期的服務。In contrast, gRPC C-core by default binds to a service with a singleton lifetime.

限定範圍存留期可讓服務執行解析具有限定範圍存留期的其他服務。A scoped lifetime allows the service implementation to resolve other services with scoped lifetimes. 例如,範圍存留期也可以透過函式插入,從 DI 容器解析 DbContextFor example, a scoped lifetime can also resolve DbContext from the DI container through constructor injection. 使用範圍存留期:Using scoped lifetime:

  • 服務實的新實例會針對每個要求而建立。A new instance of the service implementation is constructed for each request.
  • 您無法透過執行類型上的實例成員,在要求之間共用狀態。It isn't possible to share state between requests via instance members on the implementation type.
  • 預期的情況是將共用狀態儲存在 DI 容器的單一服務中。The expectation is to store shared states in a singleton service in the DI container. 儲存的共用狀態會在 gRPC 服務執行的函式中解析。The stored shared states are resolved in the constructor of the gRPC service implementation.

如需服務存留期的詳細資訊,請參閱 .NET Core 中的相依性插入For more information on service lifetimes, see .NET Core 中的相依性插入.

新增單一服務Add a singleton service

為了協助從 gRPC C 核心的執行轉換成 ASP.NET Core,您可以將服務實的服務存留期從範圍變更為 singleton。To facilitate the transition from a gRPC C-core implementation to ASP.NET Core, it's possible to change the service lifetime of the service implementation from scoped to singleton. 這牽涉到將服務實作為實例新增至 DI 容器:This involves adding an instance of the service implementation to the DI container:

public void ConfigureServices(IServiceCollection services)
{
    services.AddGrpc();
    services.AddSingleton(new GreeterService());
}

不過,具有單一存留期的服務執行,無法再透過函式插入來解析已設定範圍的服務。However, a service implementation with a singleton lifetime is no longer able to resolve scoped services through constructor injection.

設定 gRPC services 選項Configure gRPC services options

在以 C 為基礎的應用程式中,grpc.max_receive_message_lengthgrpc.max_send_message_length 等設定會在建立伺服器實例時,使用 ChannelOption 來設定。In C-core-based apps, settings such as grpc.max_receive_message_length and grpc.max_send_message_length are configured with ChannelOption when constructing the Server instance.

在 ASP.NET Core 中,gRPC 會透過 GrpcServiceOptions 類型提供設定。In ASP.NET Core, gRPC provides configuration through the GrpcServiceOptions type. 例如,gRPC 服務的傳入訊息大小上限可以透過 AddGrpc 來設定。For example, a gRPC service's the maximum incoming message size can be configured via AddGrpc. 下列範例會將 4 MB 的預設 MaxReceiveMessageSize 變更為 16 MB:The following example changes the default MaxReceiveMessageSize of 4 MB to 16 MB:

public void ConfigureServices(IServiceCollection services)
{
    services.AddGrpc(options =>
    {
        options.MaxReceiveMessageSize = 16 * 1024 * 1024; // 16 MB
    });
}

如需設定的詳細資訊,請參閱 適用于 .NET 設定的 gRPCFor more information on configuration, see 適用于 .NET 設定的 gRPC.

記錄Logging

以 C 核心為基礎的應用程式依賴 GrpcEnvironment設定記錄器以進行偵錯工具。C-core-based apps rely on the GrpcEnvironment to configure the logger for debugging purposes. ASP.NET Core 堆疊會透過記錄 API提供這種功能。The ASP.NET Core stack provides this functionality through the Logging API. 例如,您可以透過函式插入,將記錄器新增至 gRPC 服務:For example, a logger can be added to the gRPC service via constructor injection:

public class GreeterService : Greeter.GreeterBase
{
    public GreeterService(ILogger<GreeterService> logger)
    {
    }
}

HTTPSHTTPS

以 C 核心為基礎的應用程式會透過伺服器埠屬性來設定 HTTPS。C-core-based apps configure HTTPS through the Server.Ports property. 在 ASP.NET Core 中設定伺服器時,會使用類似的概念。A similar concept is used to configure servers in ASP.NET Core. 例如,Kestrel 會使用端點設定來取得這種功能。For example, Kestrel uses endpoint configuration for this functionality.

gRPC 攔截器 vs 中介軟體gRPC Interceptors vs Middleware

相較于以 C 核心為基礎的 gRPC 應用程式中的攔截器,ASP.NET Core中介軟體提供類似的功能。ASP.NET Core middleware offers similar functionalities compared to interceptors in C-core-based gRPC apps. ASP.NET Core 中介軟體和攔截器在概念上類似。ASP.NET Core middleware and interceptors are conceptually similar. Both:

  • 是用來建立處理 gRPC 要求的管線。Are used to construct a pipeline that handles a gRPC request.
  • 允許在管線中的下一個元件之前或之後執行工作。Allow work to be performed before or after the next component in the pipeline.
  • 提供 HttpContext的存取權:Provide access to HttpContext:
    • 在中介軟體中,HttpContext 是一個參數。In middleware the HttpContext is a parameter.
    • 在攔截器中,可以使用 ServerCallContext 參數搭配 ServerCallContext.GetHttpContext 擴充方法來存取 HttpContextIn interceptors the HttpContext can be accessed using the ServerCallContext parameter with the ServerCallContext.GetHttpContext extension method. 請注意,這項功能是在 ASP.NET Core 中執行的攔截器所特有。Note that this feature is specific to interceptors running in ASP.NET Core.

gRPC 攔截器與 ASP.NET Core 中介軟體的差異:gRPC Interceptor differences from ASP.NET Core Middleware:

  • 攔截器Interceptors:
    • 使用ServerCallCoNtext在抽象概念的 gRPC 層上操作。Operate on the gRPC layer of abstraction using the ServerCallContext.
    • 提供存取權:Provide access to:
      • 傳送至呼叫的已還原序列化訊息。The deserialized message sent to a call.
      • 在序列化之前,從呼叫傳回的訊息。The message being returned from the call before it is serialized.
  • 中介軟體Middleware:
    • 在 gRPC 攔截器之前執行。Runs before gRPC interceptors.
    • 在基礎 HTTP/2 訊息上操作。Operates on the underlying HTTP/2 messages.
    • 只能存取來自要求和回應資料流程的位元組。Can only access bytes from the request and response streams.

其他資源Additional resources