解决方案包括两个项目:
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>
我的两个问题:
答案 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。