2

我正在使用 Windows Azure 开展一个项目,并且在工作人员角色中我想使用 Web 服务向它提交一些信息。我的问题是:我可以在不添加服务引用的情况下使用 Web 服务吗?或者以某种方式添加它,当我在 azure 中发布我的项目时,我不需要更改服务引用?

4

1 回答 1

3

您可以使用通道工厂直接连接。这是一个示例基础存储库类,您将覆盖它,其中 T 是您的服务合同,例如 IMyService,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Microsoft.WindowsAzure.ServiceRuntime;

namespace pageengine.clients
{
    public class RepositoryBase<T> : IDisposable
    {

        #region Channel
        protected String roleName;
        protected String serviceName;
        protected String endpointName;
        protected String protocol = @"http";

        protected EndpointAddress _endpointAddress;
        protected BasicHttpBinding httpBinding;
        protected NetTcpBinding tcpBinding;

        protected IChannelFactory channelFactory;
        protected T client;

        protected virtual AddressHeader[] addressHeaders
        {
            get
            {
                return null;
            }
        }

        protected virtual EndpointAddress endpointAddress
        {
            get
            {
                if (_endpointAddress == null)
                {
                    var endpoints = RoleEnvironment.Roles[roleName].Instances.Select(i => i.InstanceEndpoints[endpointName]).ToArray();
                    var endpointIP = endpoints.FirstOrDefault().IPEndpoint;
                    if(addressHeaders != null)
                    {
                        _endpointAddress = new EndpointAddress(new Uri(String.Format("{1}://{0}/{2}", endpointIP, protocol, serviceName)), addressHeaders);
                    }
                    else
                    {
                        _endpointAddress = new EndpointAddress(String.Format("{1}://{0}/{2}", endpointIP, protocol, serviceName));
                    }

                }
                return _endpointAddress;
            }
        }

        protected virtual Binding binding
        {
            get
            {
                switch (protocol)
                {
                    case "tcp.ip":
                        if (tcpBinding == null) tcpBinding = new NetTcpBinding();
                        return tcpBinding;
                    default:
                        //http
                        if (httpBinding == null) httpBinding = new BasicHttpBinding();
                        return httpBinding;
                }
            }
        }

        public virtual T Client
        {
            get
            {
                if (this.client == null)
                {
                    this.channelFactory = new ChannelFactory<T>(binding, endpointAddress);
                    this.client = ((ChannelFactory<T>)channelFactory).CreateChannel();
                    ((IContextChannel)client).OperationTimeout = TimeSpan.FromMinutes(2);
                    var scope = new OperationContextScope(((IContextChannel)client));
                    addCustomMessageHeaders(scope);
                }
                return this.client; 
            }
        }

        protected virtual void addCustomMessageHeaders(OperationContextScope operationContextScope)
        {
            // Overidden
        }
        #endregion

        #region CTOR
        public RepositoryBase()
        {

        }
        #endregion

        #region IDisposable Members

        public virtual void Dispose()
        {
            if (client != null)
            {
                try
                {
                    ((ICommunicationObject)client).Close();
                }
                catch
                {
                    try
                    {
                        ((ICommunicationObject)client).Abort();
                    }
                    catch { } // Die quietly.
                }
            }
            if (channelFactory != null)
            {
                try
                {
                    channelFactory.Close();
                }
                catch
                {
                    try
                    {
                        channelFactory.Abort();
                    }
                    catch { } // Die quietly.
                }
                channelFactory = null;
            }
            _endpointAddress = null;
            httpBinding = null;
            tcpBinding = null;
        }

        #endregion
    }
}

然后,您将发现端点,该端点将在已发布和模拟环境中工作。扩展此基础的类可能如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

using pageengine.services.entities.account;
using pageengine.services;

namespace pageengine.clients.accounts
{
    public class AccountsRepository : RepositoryBase<IAccounts>, IDisposable
    {
        #region CTOR
        public AccountsRepository()
        {
            this.roleName = "EntitiesRole";      // Name of the role my service is on
            this.endpointName = "HttpInternal";  // Name of the endpoint configured on that role. Can be internal or input, tcp or http.
            this.serviceName = "Accounts.svc";   // Name of my service.
        }
        #endregion
    }
}

对您的服务的调用(在这种情况下来自 MVC 控制器操作)的形式为:

    public ActionResult ListAccounts()
    {
        using (var accountsRepository = new AccountsRepository())
        {
            return View("ListAccounts", accountsRepository.Client.ListAccounts());
        }
    }
于 2012-08-22T09:18:40.217 回答