我最近开始使用WCF,并且惊讶地发现Add Service Reference生成的客户端类没有实现ServiceContract
的接口(让我们称之为IMyInterface
)。相反,它实现了System.ServiceModel.ClientBase<IAnotherInterface>, IAnotherInterface
,其中IAnInterface
是一个类我的ServiceContract接口的接口,但实际上并不是同一个接口。我看到一些类型是不同的,例如它有数组而不是列表。
这对我来说有点烦人,因为有时我想远程调用Web服务,有时想使用本地对象,所以我希望它们实现相同的接口。目前我将ClientBase
对象包装在另一个对象中,因此它实现了相同的接口,并且只是将所有调用传递给ClientBase
对象。这是推荐的方法还是有更简单的方法?
我看到我可以将集合参数的类型从数组更改为List或配置服务引用上的任何内容,但怀疑这将解决基本的输入问题。
答案 0 :(得分:2)
我认为您希望将服务接口移动到单独的库(DLL /项目)中。
然后有一个SvcUtil.exe的重载,它允许您生成传递接口库(DLL)的客户端代理,以便它们不会重复。我认为旗帜是-r
或-reference
或类似的......
答案 1 :(得分:1)
您无需使用“添加服务引用”或SvcUtil。您可以手动创建使用您的界面的客户端代理。您需要在web.config中绑定,使用默认构造函数,或者您可以传入端点和绑定。
这种方法的一大优点是,每次更改界面并需要重新生成代理时,您不必使用SvcUtil.exe。您将收到编译错误,提醒您此类未正确实现您的接口。
SvcUtil和Add Service Reference主要用于您无权访问原始服务接口或合同的远程服务。该实用程序只是读取服务wsdl并为您生成一个。因此,疯狂的命名,以确保它不会与项目中已有的东西发生冲突。
另外,正如Reddog所说,将服务和数据合同移动到另一个项目/ dll可以让您更容易地参考这些。
public partial class MyServiceClient : System.ServiceModel.ClientBase<MyProject.Contracts.IMyService>, MyProject.Contracts.IMyService
{
#region IMyService Members
public void RecordSearchAnalytics(int a, int b, int c, string d, string e)
{
base.Channel.RecordSearchAnalytics(a, b, c, d, e);
}
#endregion
#region boiler plate code
public MyHServiceClient()
{
}
public MyHServiceClient(string endpointConfigurationName) :
base(endpointConfigurationName)
{
}
public MyHServiceClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}
public MyHServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}
public MyHServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}
#endregion
}
答案 2 :(得分:0)
WCF的默认行为正是您所看到的:服务和客户端完全彼此独立 - 毕竟是可互操作的想法,您不能依赖客户端也是.NET - 它可能是Ruby,Python - 你可以命名。
因此,当创建客户端代理时,客户端和服务共享的唯一内容是线上消息的格式,而在SOAP的情况下,服务的WSDL描述。客户端代理基于此元数据进行重新创建,目标是提供相同的方法来调用,以及用于将消息序列化到服务的相同数据结构。
如果您可以控制通信的两端并且都是.NET,那么您可以通过将服务和数据协定放入单独的类库并共享该程序集(以及那些精确的接口和服务和客户之间的类)。
当您的客户端项目引用该共享程序集时,现在添加服务引用并在对话框中保留默认选项,那么行为是尽可能重用引用程序集中的任何现有类和接口。因此,在这种情况下,如果添加服务引用,客户端代理的生成器将找到与您的服务描述完全匹配的类,并且只使用这些类而不是生成单独的,独立的类和接口集。