2

Windows Azure を使用するプロジェクトに取り組んでおり、worker ロール内で 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 に答える