首页 > 解决方案 > WPF MVVM gRPC 如何管理连接凭据?

问题描述

我正在创建使用多个 gRPC CRUD 服务的 WPF 应用程序。通常,我会创建一个 GrpcChannel 实例并使用此通道填充 gRPC 客户端,将它们传递给 DI 容器以在 ViewModels 中进一步使用。

但问题是我的 WPF 应用程序有某种“启动窗口”,用户必须提供服务器凭据(ip 和端口)才能连接。这一事实导致了我无法在应用程序实际启动之前使用 gRPC 客户端实例化 GrpcChannel 并将它们传递给 DI 容器的问题。我应该在用户传递服务器凭据后以某种方式创建 GrpcChannel 并将此通道用于所有 gRPC 客户端。

那么,问题是如何正确管理应该在运行时使用用户凭据创建通道的情况?

标签: c#wpfmvvmdependency-injectiongrpc

解决方案


这些选项怎么样?

选项 1 - 在调用 gRPC 之前检查空凭据(这就是我所做的)

public interface IGrpcCredentials
{
    string? GetIP();
    int? GetPort();
}

用法

public void TryCallGrpcService(){
    IGrpcCredentials credentials; //pretend this has been passed here from somewhere

    var ip = credentials.GetIP();
    if(ip is null){
        return;
    }

    var port = credentials.GetPort();
    if(port is null){
        return;
    }

    CallGrpcService((string)ip, (int)port);
}

选项 2 - 使用占位符服务初始化 DI

您可以使用不提供凭据的占位符服务来初始化 DI。例如:

public interface IGrpcCredentials
{
    bool AreCredentialsAvailable();
    string GetIP();
    int GetPort();
}

public class RealGrpcCredentials
{
    private readonly string _ip;
    private readonly int _port;

    public RealGrpcCredentials(string ip, int port)
    {
        _ip = ip;
        _port = port;
    }

    bool AreCredentialsAvailable() => true;
    string GetIP() => _ip;
    int GetPort() => _port;
}

public class PlaceholderGrpcCredentials
{
    bool AreCredentialsAvailable() => false;
    string GetIP() => return string.Empty;
    int GetPort() => return -1;
}

用法

// register palceholder before knowing the credentials
container.Register<IGrpcCredentials, PlaceholderGrpcCredentials>();

//ask user for their crednetials
var credentials = ShowUserCredentialsDialog();

//register the actual credentials
container.Register<IGrpcCredentials, RealGrpcCredentials>(new RealGrpcCredentials(credentials.Ip, credentials.Port));

选项 3 - 在用户输入其凭据后初始化 DI

在初始化 DI 容器之前等待用户填写其凭据。您必须创建一个不依赖于 DI 的启动窗口,并且可以在构建 DI 容器之前启动。


推荐阅读