开发和使用 WCF 服务 - 分离服务、合约、代理和客户端






1.65/5 (6投票s)
描述如何为大型企业系统开发和消费 WCF 服务
关于 WCF 的一些说明
WCF 是微软统一的通信平台,是首选的 SOA 开发选择,就像之前的 asmx Web 服务一样。 WCF 提供了所有强大的跨平台通信需求,并且可以在 IIS、Windows 应用程序、控制台应用程序、Windows 服务、MSMQ 和各种协议(例如 http、命名管道、TCP 等)和绑定中灵活地进行托管。
问题所在
在 Visual Studio 中,WCF 服务的开发就像 asmx Web 服务一样简单,但是服务、终结点(.svc 文件)、合约和配置都混杂在一个项目中。 而且,我们需要维护一个大型的 web.config 文件。 大多数 WCF 托管和绑定配置都位于服务配置文件中。 传统上,我们需要在每个项目中创建代理来使用 WCF 服务,因此,如果我们需要在多个项目中消费 WCF 服务,则需要在不同的项目中创建相同的代理类。 这是代码重复。 并且,如果 WCF 服务发生任何更改,我们需要更改每个项目的配置文件和代理。
解决方案
如果我们有一个适用于所有项目的代理,将合约和服务分离,并在托管环境中维护配置,而不是在服务内部维护配置,则更适合大型企业系统,因为这使得 WCF 服务如何暴露取决于宿主(配置位于宿主端,而不是服务端)。 我开发了一个示例,将服务、合约、宿主和代理与客户端分离。
代码讨论
我创建了 5 个不同的项目,分别用于合约、服务、宿主、代理和客户端。
合约和服务项目是类库,没有任何配置文件。
WCF 代理也是一个类库,客户端是一个 Windows 应用程序,代理和客户端几乎具有相同的配置条目。
该服务暴露了两个简单的方法:GetPrice 和 GetProductName。
这里的代理类派生自 ClientBase
我们还可以使用 channelFactory 的 CreateChannel 方法创建通道,并通过创建的通道调用服务。
//WCF 代理类
namespace WCFProxy
{
public class Proxy:ClientBase
{
public string GetProductName(int ProductID)
{
return Channel.GetProductName(ProductID);
}
public string GetPrice(int ProductID)
{
return Channel.GetPrice(ProductID);
}
}
}
<configuration>
<system.serviceModel>
<services>
<service name="WCFService.AWService">
<endpoint address="net.tcp://:9005/AWEndPoint" binding="netTcpBinding" contract="WCFContracts.IAWContract" />
</service>
</services>
</system.serviceModel>
</configuration>/>
//WCF 托管
public static void Main() {
svcHost.Open();
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.WriteLine("服务正在运行...");
Console.ReadLine();
}
<configuration>
<system.serviceModel>
<endpoint address="net.tcp://:9005/AWEndPoint"
binding="netTcpBinding" contract="WCFContracts.IAWContract" />
</client>
</system.serviceModel>
</configuration>