在Visual Studio中向Web服务(这是所有WCF)添加服务引用会生成一些生成的代码,包括对要公开的接口的客户端重新声明。
我理解为什么会生成此界面:您可能正在使用第三方服务而无法访问实际界面。
但我确实如此,即使透明代理确实实现了我想要转换的接口,这两个 赋值兼容。
我可以使用反射,但这很难看。有没有办法打败这种虚拟类型的安全性并注入元数据,以便我可以使用类的接口?
我的具体问题以复杂的方式偏离了常规,这种方式与单个客户端有关,该客户端直接使用基类的某些派生类,并通过服务引用远程使用其他客户端。每个服务器的基类需要保持对集合中的订阅客户端的引用以进行枚举以通知事件,并且由于使用代理而导致问题类型不同。
这些答案都没有解决我的具体问题,但每一个答案都是有益的,有帮助的。我找到了自己的解决方案(使用双重绑定),但如果你没有从根本上改善我对整个业务的理解,我就永远不会想到它。
三个优秀的答案。如何选择一个?我选择第一个,因为它直接解决了我第一次思考的问题。
答案 0 :(得分:4)
如果您已经在客户端拥有合同dll,您甚至不需要服务引用(除非您使用它来为您编写设置代码) - 您可以简单地继承ClientBase并公开Channel,并使用直接 - 像(没有IDE方便......):
public class WcfClient<T> : ClientBase<T> where T : class
{
public new T Channel {get {return base.Channel;}}
}
然后你可以做以下事情:
using(var client = new WcfClient<IFoo>())
{
client.Channel.Bar(); // defined by IFoo
}
您仍然需要配置中的配置设置来确定地址,绑定等 - 但比代理生成更少杂乱。此外,您可以选择重新实现IDipsoable
来处理WCF代理可以引入Dispose()
的事实(这很糟糕):
public class WcfClient<T> : ClientBase<T>, IDisposable where T : class
{
public new T Channel {get {return base.Channel;}}
void IDisposable.Dispose() {
try {
switch(State) {
case CommunicationState.Open: Close(); break;
// etc
}
} catch {} // swallow it down (perhaps log it first)
}
}
答案 1 :(得分:2)
添加服务引用时,请转到“高级”并确保选中“在引用的程序集中重用类型”,并选择包含接口定义的程序集。您也可以使用现有服务引用执行此操作,方法是右键单击它并转到“配置”。
答案 2 :(得分:1)
要从服务返回接口,您需要使用KnownType属性:
如果您想从服务中返回自定义类型:
有没有帮助?