首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Monotouch/ wcf :如何在没有svcutil的情况下使用wcf服务

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

Stack Overflow用户
提问于 2012-04-07 20:41:34
回答 2查看 7.5K关注 0票数 13

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

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

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

==========

代码语言:javascript
复制
        ChannelFactory<IMyContract> factory = new ChannelFactory<IMyContract>(binding, endpointAddress);
        return factory.CreateChannel();   

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-08 00:56:01

ChannelFactory<T>有一个虚方法CreateChannel()。如果它没有被覆盖,它将使用动态代码生成,这在MonoTouch上会失败。

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

下面是我的一个旧的服务实现,它至少用于MonoTouch。我将它分成两个部分类-第一个类在所有版本中都是链接的,第二个只在iOS版本中链接(允许动态生成机制仍然在windows上工作)。

我已经将它简化为只包含一个服务调用。

TransactionService.cs:

代码语言:javascript
复制
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 )

代码语言:javascript
复制
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()重写。我已经清理了要匹配的示例代码。

EDIT2:我添加了一个异步方法实现。

票数 20
EN

Stack Overflow用户

发布于 2012-04-07 21:19:07

我认为你可能会混淆这里的术语-- ChannelFactory是一个泛型类型,而不是一个动态

根据MonoTouch文档,虽然有limitations to the Generics support in MonoTouch,但ChannelFactory应该可以在这里使用。

你试过使用ChannelFactory吗?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10054581

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档