代理的构造函数

时间:2013-08-30 14:16:37

标签: wcf proxy

解决方案包括两个项目:

DemoService项目,它是一个实现IGetHeaders接口的简单WCF服务库。此接口由单个方法(GetHeaders)组成,该方法检索有关发送到服务的消息中的标头的一些信息。对于本练习,它将返回Action标题。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Channels;

namespace DemoService
{
     public class HeaderService : IGetHeaders
     {
         public string GetHeaders()
         {
             return OperationContext.Current.RequestContext.RequestMessage.Headers.Action;
         }
      }
 }

TestClient项目,它是一个控制台应用程序,使您可以使用DemoService服务。已经创建了DemoService的代理。

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

namespace TestClient
{
     class Program
     {
         static void Main(string[] args)
         {
             DemoService.GetHeadersClient proxy = new DemoService.GetHeadersClient("TcpIGetHeaders");
             Console.WriteLine("And the header is: " + proxy.GetHeaders());
             Console.ReadLine();
         }
      }
 }

在对象的构造函数中,传递绑定的名称以用作唯一参数。 app.config文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
             <binding name="WsIGetHeaders" />
            </wsHttpBinding>
         <netTcpBinding>
             <binding name="TcpIGetHeaders" />
         </netTcpBinding>
        </bindings>
        <client>
              <endpoint address="http://localhost:8731/Design_Time_Addresses/DemoService/HeaderService/"
              binding="wsHttpBinding" bindingConfiguration="WsIGetHeaders"
              contract="DemoService.IGetHeaders" name="WsIGetHeaders">
              </endpoint>
              <endpoint address="net.tcp://localhost:8731/Design_Time_Addresses/DemoService/HeaderService/"
              binding="netTcpBinding" bindingConfiguration="TcpIGetHeaders"
              contract="DemoService.IGetHeaders" name="TcpIGetHeaders">
              </endpoint>
         </client>
        </system.serviceModel>
     </configuration>

我的两个问题:

  1. 在服务代码中,没有构造函数。为什么在代理对象中,我们可以传递一个唯一的参数。
  2. 为什么参数是名称必须是端点的名称,这里是=“TcpIGetHeaders”。

1 个答案:

答案 0 :(得分:1)

该服务确实有一个构造函数 - 由于没有显式定义,因此编译器提供了一个默认的无参数构造函数。以下代码行将创建服务的新实例,即使其中没​​有定义明确的构造函数:

HeaderService myService = new HeaderService();

代理对象没有创建服务的实例 - 它正在创建一个可以与服务通信的对象。添加服务引用时,.NET会生成用于创建代理的代码,以及调用服务公开的方法。

如果查看reference.cs文件,您将看到代理的自动生成代码。此代理继承自ClientBase<T>并实现定义服务的接口。

DemoService.GetHeadersClient proxy = new DemoService.GetHeadersClient("TcpIGetHeaders");

上面的代码调用自动生成的GetHeadersClient类构造函数,而不是服务构造函数。 ClientBase<T>的构造函数有几个重载 - 在上面的代码的情况下,它使用构造函数来获取指定的端点配置(由name元素中的endpoint元素确定配置文件)。

如果你打开了refernce.cs文件,你可能会看到与此类似的代码(使用较旧的示例,因此版本号可能与您的情况不同,我对命名空间进行了有根据的猜测):

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class HeaderServiceClient : System.ServiceModel.ClientBase<TestService.DemoService.IGetHeaders>, TestService.DemoService.IGetHeaders 
{

    public HeaderServiceClient() 
    {
    }

    public HeaderServiceClient(string endpointConfigurationName) : 
        base(endpointConfigurationName) 
    {
    }

    public HeaderServiceClient(string endpointConfigurationName, string remoteAddress) :
        base(endpointConfigurationName, remoteAddress) 
    {
    }

    public HeaderServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
        base(endpointConfigurationName, remoteAddress) 
    {
    }

    public HeaderServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
        base(binding, remoteAddress) 
    {
    }

    public string GetHeadesr() 
    {
        return base.Channel.GetData(value);
    }
}

注意具有参数的构造函数如何引用ClientBase<T>的基础构造函数。

总之,您正在调用代理的构造函数,并且您正在使用为端点配置接受字符串的重载。

有关详细信息,请参阅ClientBase(T Channel) Constructor