WPF MVVM gRPC как управлять учетными данными для подключения?

#c# #wpf #mvvm #dependency-injection #grpc

Вопрос:

Я создаю приложение WPF, которое использует несколько служб gRPC CRUD. Обычно я создавал экземпляр GrpcChannel и заполнял клиентов gRPC, используя этот канал, передавал их в контейнер DI для дальнейшего использования в моделях просмотра.

Но дело в том, что в моем приложении WPF есть своего рода «Окно запуска», в котором пользователь должен предоставить учетные данные сервера (ip и порт) для подключения. Этот факт приводит к проблеме, из-за которой я не могу создать экземпляр GrpcChannel с клиентами gRPC и передать их в контейнер DI до фактического запуска приложения. Я должен каким-то образом создать GrpcChannel после того, как пользователь передал учетные данные сервера, и повторно использовать этот канал для всех клиентов gRPC.

Итак, вопрос в том, как правильно управлять ситуацией, когда канал должен быть создан во время выполнения с учетными данными пользователя?

Ответ №1:

Как насчет этих вариантов?

Вариант 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() =gt; true;  string GetIP() =gt; _ip;  int GetPort() =gt; _port; }  public class PlaceholderGrpcCredentials {  bool AreCredentialsAvailable() =gt; false;  string GetIP() =gt; return string.Empty;  int GetPort() =gt; return -1; }  

Использование

 // register palceholder before knowing the credentials container.Registerlt;IGrpcCredentials, PlaceholderGrpcCredentialsgt;();  //ask user for their crednetials var credentials = ShowUserCredentialsDialog();  //register the actual credentials container.Registerlt;IGrpcCredentials, RealGrpcCredentialsgt;(new RealGrpcCredentials(credentials.Ip, credentials.Port));  

Вариант 3 — Инициализируйте DI после того, как пользователь введет свои учетные данные

Дождитесь, пока пользователь заполнит свои учетные данные, прежде чем инициализировать контейнер DI. Вам нужно будет создать стартовое окно, которое не зависит от DI и может быть запущено до создания контейнера DI.