【问题标题】:How to make WPF MVVM application connect to multiple WCF Services?如何使 WPF MVVM 应用程序连接到多个 WCF 服务?
【发布时间】:2012-07-08 21:49:57
【问题描述】:

我已经开发了 4 个 WCF 服务。

每个服务负责其他事情。

每个服务都有一个UserNamePasswordValidator,因此客户端在连接时需要提供凭据。

我现在想在 MVVM 架构中开发我的 WPF 客户端应用程序。

我希望 WPF 应用程序加载一个'登录'屏幕,

用户输入用户名和密码的地方,

然后这将被传递给 4 个 WCF 服务的 4 个客户端(都使用相同的用户名和密码)。

最好的方法是什么?

客户在哪里?在“模型”部分?哪个视图的模型?

WCF 服务需要被多个视图使用,所以我认为我不能将任何 WCF 服务客户端放在一个特定的模型类中...

【问题讨论】:

    标签: wpf wcf mvvm loginview


    【解决方案1】:

    为此,我们创建了一个 ServiceFactory 类,该类连接到给定端点和适当的IClientChannel 派生接口的服务。这假设您直接使用 WCF 服务,例如不是通过 VS 生成的代理,因为您需要在每个客户端通道创建时设置用户名和密码值。

    客户端通道接口与服务工厂一起位于外部“服务库”中,因此它们可以与 WCF 服务实现和客户端共享。我们将凭据存储在静态字典中(尽管您也将其放入主资源字典中),密码保存在 SecuredString 中,以提高安全性。

    我已经在博客上描述了创建这样一个服务工厂的基本过程:

    http://blog.kutulu.org/2012/03/proxy-free-wcf-ditching-proxy.html

    在我们的例子中,我们在App.xaml.cs 中执行设置例程,提示输入凭据并尝试调用我们的服务之一,循环直到我们成功登录。该代码要复杂得多,但基本上是:

    while (true)
    {
      var factory = new ChannelFactory<ITestChannel>(new WSHttpBinding("SecuredBinding"));
      ITestChannel client = null;
      try
      {
        factory.Credentials.UserName.UserName = logOnModel.UserName;
        factory.Credentials.UserName.Password = logOnModel.Password;
    
        var address = Settings.Default.TestServiceUrlBase));
        client = factory.CreateChannel(address);
    
        break;
      }
      // Catch various exceptions here.
    }
    

    这里的窍门是,如果您的登录名或密码错误并且您的UsernamePasswordValidator 登录失败,您将收到一个MessageSecurityException,这将使您的频道出错,因此您需要关闭它并打开一个新的一个。但是一旦打开第一个通道,您就无法更改 ChannelFactory 上的凭据,因此您每次都需要处理并重新创建新的工厂和新的客户端通道。

    我们还会在此处检查CommunicationExceptionArgumentException,以防网址错误。

    完成后,您可以在服务工厂类中使用类似的代码来构造一个客户端,给定其通道接口,并为每个调用设置凭据。 (我们实际上为每个不同的接口缓存服务工厂,因为我们经常创建和销毁通道,但这取决于你。)

    【讨论】:

    • 在我们的例子中 - 客户端是使用 Visual Studio 的“添加服务引用”创建的。在调用“Open()”方法之前,凭据会简单地传递给生成的客户端。所以 - 我不确定你的方法是否适合我的情况......
    • 您仍然可以使相同的想法发挥作用——创建频道的工厂类——它只是不会那么优雅。 VS 服务参考确实为其底层客户端接口创建了一个IClientChannel 接口,这可能会有所帮助。或者,如果数量足够小,您可以简单地为每个服务创建一个方法。
    • 我有 4 项服务。够小吗?我只是很难理解这一切是如何联系起来的。所以我有一个用于“服务客户端”的 DLL,其中包含工厂,但谁发起了这个? “登录模型”?服务的实例存储在哪里?
    • 在我们的例子中,我们在 App.xaml.cs 中的应用设置代码中对服务进行初始调用,但您绝对可以将其放入您的 LoginModel 代码中。 (我们的 LoginModel 只是从用户那里获取凭据并存储它们)。对于其余部分,它在博客文章(带图片)中得到了更好的解释,但是如果您更喜欢使用 VS 自动生成的客户端,您仍然可以为此创建一个工厂类,您只是无法创建一个打开的方法多种类型的代理。
    • 一旦他们设法连接到服务,客户端存储在哪里?据我了解-一旦处理了“LoginView”并显示了“MainWindow”-“LoginModel”也被处理了,那么-我们究竟在哪里保留“实时”客户端连接,以便所有视图现在可以使用它们了吗?
    猜你喜欢
    • 2014-10-28
    • 2015-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多