我有一个WPF应用程序,到目前为止只是客户端,但现在我正在努力将其拆分为客户端和服务器端。在这项工作中,我正在为客户端 - 服务器通信引入WCF。我的应用程序有几个项目,并且需要多个项目的服务引用。
分离的最初努力是“直截了当”地做所有事情。需要与服务通信的所有项目都获得服务引用,主WPF应用程序项目也是如此 - 在那里获取app.config。我觉得这很快变成一团糟,我无法想象这是人们使用的典型架构吗?我也看到了每个服务引用生成DataContract类的新实现这一事实的问题 - 因此在项目交叉上没有对DataContract类的共同理解。我在一个项目中有一些ViewModel类,另一个项目实现了一些ViewModel。我想传递从服务中收到的对象,但我不能,因为每个项目中收到的对象的生成的客户端表示不同。
那么 - 是否有建议使用WCF构建此类客户端/服务器分离的方法?还是要遵循的原则?我在想客户端上使用的一个常见代理项目,它与服务进行通信,包装接收到的数据,并在客户端库知道的表单上返回数据。应该只提供一个服务引用,我想我只需要wpfApp项目中的App.config?这有意义吗?
答案 0 :(得分:16)
我喜欢这样构建我的WCF解决方案:
合同(类库)
包含所有服务,操作,故障和数据协定。可以在纯.NET-to-.NET场景中在服务器和客户端之间共享
服务实施(类库)
包含实现服务的代码,以及实现此目的所需的任何支持/帮助程序方法。没别了。
服务主机(可选 - 可以是Winforms,Console App,NT Service)
包含用于调试/测试的服务主机,或者也可能用于生产。
这基本上给了我服务器方面的东西。
在客户端:
客户端代理(类库)
我喜欢将我的客户端代理打包到一个单独的类库中,以便它们可以被多个实际的客户端应用程序重用。这可以使用svcutil或“添加服务引用”并手动调整生成的可怕的app.config,或者通过使用ClientBase<T>
或ChannelFactory<T>
构造手动实现客户端代理(共享契约程序集时)来完成
1-n个实际客户(任何类型的应用)
通常只会引用客户端代理程序集,或者也可能引用契约程序集(如果它正在共享)。这可以是ASP.NET,WPF,Winforms,控制台应用程序,其他服务 - 您可以命名。
这是受到Miguel Castro的Extreme WCF screen cast在DotNet Rocks电视上与Carl Franklin的启发 - 强烈推荐的屏幕演员!
答案 1 :(得分:1)
这取决于。 WCF是一个很大的框架,它意味着跨越很多不同的场景。
但对于像你这样简单的应用程序,当你不关心像Java互操作或通用Web服务互操作这样的东西时,这就是我的工作:
所有DataContract类和ServiceContract接口都进入客户端和服务器之间共享的库(或多个库)。请注意,您可能不应该使用ServiceContract来装饰您的服务实现,您可以使用ServiceContract属性创建一个单独的接口,您可以将其放在共享程序集中。
所以你似乎正在做正确的事情。您可能不需要的是在这种情况下自动生成代理。这只会让你感到痛苦。因此,请不要使用“添加服务引用”对话框来执行您的操作。只需包含您的共享DataContract程序集并使用ChannelFactory获取共享库中定义的服务接口的代理。这也使您不必在Visual Studio中继续重新生成代理,对于任何体面的项目,它都会变得非常快。
如果你要走这条路线,你也可以摆脱MetaDataExchange端点,因为只需要描述客户端的服务。由于您在共享程序集中执行所有操作,因此您不需要服务描述,因为您已经以代码形式获得了服务描述。
答案 2 :(得分:1)
我使用的通常结构是:
Common - 包含接口,数据合同,服务合同,抽象类等; 客户端 - 引用Common,包含服务器代理类; 服务器 - 引用Common,包含实际的实现类;