我有一个非常复杂的服务主机,它包含多个DUPLEX服务。它们提供了一些常见功能(Connect,Disconnect,KeepAlive等等),但除此之外,它们还提供了非常具体的功能。
我的所有服务都从公共基类继承(抽象)。
所以,我也负责客户端应用程序的一部分,我希望在基类中处理连接,断开连接,保持活动ping和重新连接(等等)的管理官僚处理,这样我就可以遵守DRY原则并强制其他开发人员不要实现自己的连接处理。
有没有办法让WCF公开服务基类,这样我就可以为客户端应用程序中的官僚浪费时间创建一个公共包装类?
我真的不希望看到未来客户端组件的每个开发人员都创建自己的包装器吗?
而且,如果你允许咆哮:
为什么,为什么,为什么微软如此完全不了解清洁代码开发的最佳实践和基本原则?它与这个INotifyPropertyChanged相同 - 其中一个人被迫编写大量不必要的重复代码,而不是提供一个简单的属性来通知属性......
答案 0 :(得分:4)
我不知道让多个WCF代理从公共基类继承的好方法。您可以手动编辑添加服务引用时生成的代码,但这对可维护性不利。
但是,如果您在客户端和服务器之间共享合同程序集,则可以让多个代理使用相同的基本接口。然后,您可以编写一个客户端辅助类(可能使用扩展方法)来在基接口上执行常见操作。您也可以将帮助程序类放在共享程序集中,并从多个客户端重用它。
虽然我没有使用双面打印,所以我不确定是否会引入并发症。
例如,假设您有两个服务Calculator和Echo,并且每个服务都需要实现Keepalive方法。您可以定义三个服务合同接口:
[ServiceContract]
public interface IStatefulService
{
[OperationContract]
void KeepAlive(int sessionID);
}
[ServiceContract]
public interface ICalculator : IStatefulService
{
[OperationContract]
int Add(int a, int b);
}
[ServiceContract]
public interface IEcho : IStatefulService
{
[OperationContract]
string Echo(string message);
}
您可以将服务合约接口放在客户端和服务器共享的公共类库中。
在服务器上,您将拥有ServiceBase类,该类将实现IStatefulService并包含keepalive处理代码。你有一个从ServiceBase派生并实现ICalculator的具体CalculatorService;和一个从ServiceBase派生并实现IEcho的具体EchoService。
在客户端上,您需要两个代理,每个服务一个。从理论上讲,您可以使用“添加服务引用”生成代理,使用“引用程序集中的重用类型”复选框 - 但我遇到了这个问题。相反,您可以直接使用ChannelFactory,如下所示:
var echoer = (new ChannelFactory<IEcho>("")).CreateChannel();
Console.WriteLine(echoer.Echo("hello"));
var calculator = (new ChannelFactory<ICalculator>("")).CreateChannel();
Console.WriteLine(calculator.Add(2, 3));
(在生产代码中,你想要重用通道工厂,而不是像这样动态创建它们。而且你将处理代理,并且你有错误处理......)
您还需要在客户端配置文件中设置端点。
一旦您的两个代理共享一个基本接口,您就可以编写一个实用程序类来帮助您使用该接口。