在不添加服务引用的情况下,在同一解决方案中添加WCF引用

时间:2012-08-22 08:36:18

标签: c# wcf web-services azure cloud

我正在使用Windows Azure开发一个项目,并且在一个辅助角色中我想使用web服务向它提交一些信息。我的问题是:我可以使用webservice而不添加服务引用吗?或以某种方式添加它,当我在azure中发布我的项目时,我不需要更改服务引用?

1 个答案:

答案 0 :(得分: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());
        }
    }