Monotouch/WCF:如何在没有 svcutil 的情况下使用 wcf 服务

编程入门 行业动态 更新时间:2024-10-05 11:18:12
本文介绍了Monotouch/WCF:如何在没有 svcutil 的情况下使用 wcf 服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

因为monotouch编译为本机代码,所以有一些限制,比如不允许动态调用.

Becuase monotouch compile to native code, so it has some limitation such as dynamic invoke is not allowed.

但是我在 中有很多类,我使用 ChannelFactory 动态调用 wcf 服务: new ChannelFactory(myBinding, myEndpoint);现在在 monotouch 我应该使用 slsvcutil 来生成 wcf 代理类,但是 slsvcutil 生成了很多不必要的额外代码(巨大的),并且由于通过 ClientBase 类与 WCF 基础结构的高耦合,使得消费者难以进行单元测试.

But I have a lot class in , that I use the ChannelFactory dynamic to invoke the wcf service: new ChannelFactory(myBinding, myEndpoint); Now in monotouch I should use the slsvcutil to generate the wcf proxy class, but the slsvcutil generate a lot of Unnecessary extra code (huge), and Makes consumers difficult to unit test, due to high coupling with the WCF infrastructure through the ClientBase class.

除了ChannelFactory还有更好的解决方案吗?我宁愿手动编写代码,对如何调用服务(例如 ChannelFactory)有更多的控制权.

Is there a better solution except the ChannelFactory? I would rather write the code manually, have more control over how services are invoked such as the ChannelFactory.

==========

ChannelFactory<IMyContract> factory = new ChannelFactory<IMyContract>(binding, endpointAddress); return factory.CreateChannel();

//==> 抛出异常:MonoTouch 不支持动态代理代码生成.覆盖此方法或其调用者以返回特定的客户端代理实例

//==> It throw exception: MonoTouch does not support dynamic proxy code generation. Override this method or its caller to return specific client proxy instance

推荐答案

ChannelFactory 有一个虚方法 CreateChannel().如果这不被覆盖,它使用动态代码生成,在 MonoTouch 上失败.

ChannelFactory<T> has a virtual method CreateChannel(). If this is not overridden, it uses dynamic code generation, which fails on MonoTouch.

解决方案是覆盖它并提供您自己的编译时实现.

The solution is to override it and provide your own compile-time implementation.

下面是我的一个旧的服务实现,至少曾经在 MonoTouch 上工作过.我将它分成 2 个部分类 - 第一个在所有构建中链接,第二个仅在 iOS 构建中(允许动态生成机制仍然在 Windows 上工作).我已将其精简为仅包含 1 个服务调用.

Below is an old service implementation of mine that at least used to work on MonoTouch. I split it up into 2 partial classes - the first one being linked in all builds, the 2nd only in the iOS builds (allowing the dynamic generation mechanism to still work on windows). I've stripped it down to only contain 1 service call.

TransactionService.cs:

TransactionService.cs:

public partial class TransactionService : ClientBase<IConsumerService>, IConsumerService { public TransactionService() { } public TransactionService(string endpointConfigurationName) : base(endpointConfigurationName) { } public TransactionService(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public TransactionService(string endpointConfigurationName, EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public TransactionService(Binding binding, EndpointAddress remoteAddress) : base(binding, remoteAddress) { } public AccountBalanceResponse GetAccountBalance( AccountBalanceQuery query ) { return Channel.GetAccountBalance( query ); } }

TransactionService.iOS.cs:ConsumerServiceClientChannel 通过反射执行调用)

TransactionService.iOS.cs: ConsumerServiceClientChannel which executes the calls via reflection)

public partial class TransactionService { protected override IConsumerService CreateChannel() { return new ConsumerServiceClientChannel(this); } private class ConsumerServiceClientChannel : ChannelBase<IConsumerService>, IConsumerService { public ConsumerServiceClientChannel(System.ServiceModel.ClientBase<IConsumerService> client) : base(client) { } // Sync version public AccountBalanceResponse GetAccountBalance(AccountBalanceQuery query) { object[] _args = new object[1]; _args[0] = query; return (AccountBalanceResponse)base.Invoke("GetAccountBalance", _args); } // Async version public IAsyncResult BeginGetAccountBalance(AccountBalanceQuery query, AsyncCallback callback, object asyncState ) { object[] _args = new object[1]; _args[0] = query; return (IAsyncResult)base.BeginInvoke("GetAccountBalance", _args, callback, asyncState ); } public AccountBalanceResponse EndGetAccountBalance(IAsyncResult asyncResult) { object[] _args = new object[0]; return (AccountBalanceResponse)base.EndInvoke("GetAccountBalance", _args, asyncResult); } } }

我刚刚用最新的 MT (5.2) 测试了这个 - 它不再需要我以前在那里的所有额外的样板,只需要 CreateChannel() 覆盖.我已经清理了示例代码以匹配.

I just tested this with the latest MT (5.2) - it no longer needs all that extra boiler plate I had in there before, just the CreateChannel() override. I've cleaned up the sample code to match.

我添加了一个异步方法实现.

I added an async method implementation.

更多推荐

Monotouch/WCF:如何在没有 svcutil 的情况下使用 wcf 服务

本文发布于:2023-11-12 21:02:22,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1582523.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:情况下   如何在   WCF   Monotouch   svcutil

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!