题
在 Visual Studio 中添加对 Web 服务(这都是 WCF)的服务引用会生成一些生成的代码,包括所公开接口的客户端重述。
我明白为什么生成这个界面了:您可能正在使用第三方服务,但无法访问实际界面。
但我愿意,而且两个人都是 不是 分配兼容,即使透明代理确实完全实现了我想要转换的接口。
我可以使用反射,但这很丑陋。有没有什么方法可以克服这种虚假类型安全性并注入元数据,以便我可以将接口与类一起使用?
我的具体问题以复杂的方式偏离了规范,这些问题与直接使用基类的某些派生类并通过服务引用远程使用其他派生类的单个客户端有关。每个服务器的基类需要在集合中保留对订阅客户端的引用,以进行枚举以通知事件,并且由于使用代理而导致类型变化。
这些答案都没有解决我的具体问题,但每个答案都具有启发性和帮助性。我找到了自己的解决方案(使用双重绑定),但如果你没有从根本上提高我对整个业务的理解,我永远不会弄清楚它。
三个出色的答案。怎样才能只选一个呢?我选择第一个,因为它直接解决了我首先遇到的问题 想法 我有过。
解决方案
当您添加服务引用,进入“高级”,并确保“中引用组件重用类型”选择和被选择包含您的接口定义组装。您也可以通过右击它现有的服务参考,并要“配置”。
做到这一点其他提示
如果您已经拥有客户合同的dll,你甚至不需要的服务引用(除非你用它来写你的设置代码) - 你可以简单的子类ClientBase并露出通道,并使用直接 - 像(没有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)
}
}
为了从服务返回接口,您需要使用 KnownType 属性:
-
如果您想从服务返回自定义类型:
这些有帮助吗?