WCF学习笔记 2

2019-08-28 14:50:49 浏览数 (1)

在学习WCF的ABCB之前,我们先创建一个NetNamedPipeBinding绑定方式的服务。

理解契约式编程

契约合同能保障双方的利益,对客户来说,合同规定了供应者要做的工作;对供应者来说,合同说明了如果约定的条件不满足,供应者没有义务一定要完成规定的任务。该道理同样也适用于软件. 所以,契约式编程是编程的一种方法。

引入契约观念之后,这种Client 与 Server 关系被打破,大家都是平等的,你需要我正确提供服务,那么你必须满足我提出的条件,否则我没有义务“排除万难”地保证完成任务。

WCF服务契约

服务契约描述了暴露给外部的类型、以及所支持的操作、使用的消息交换模式和消息的格式。每个WCF服务必须实现至少一个服务契约。

使用服务契约必须要引用命名空间System.ServiceModel

ServiceContractAttribute:

该特性可被用来作用于类或者接口之上,并允许重复声明。

OperationContractAttribute:

只有定义了该特性的方法才会被放入服务之中。

新建一个类库,命名为HelloService

添加引用System.ServiceModel

然后新建一个接口IHelloService.cs:

代码语言:javascript复制
[ServiceContract]
public interface IHelloService
{
  [OperationContract]
  string SayHello(string name);
}

添加HelloService类:

代码语言:javascript复制
public class HelloService : IHelloService
{
  public string SayHello(string name)
  {
    return "Hello, I am "   name;
  }
}

ServiceHost类型:当IIS活WAS作为宿主程序时,IIS和WAS会自动创建ServiceHost类型。

手动创建的基本语法:public ServiceHost(Type serviceType,params Uri[] baseAddresses);

新建宿主

新建项目HelloServiceHost(控制台应用程序)

添加System.ServiceModel引用,和项目引用HelloService,引用之前的类库项目。

HelloServiceHost 项目中Program.cs代码如下:

代码语言:javascript复制
using (MyHelloHost host = new MyHelloHost())
{
  host.Open();
  Console.ReadLine();
}

MyHelloHost类如下:

代码语言:javascript复制
public class MyHelloHost : IDisposable
{
  /// <summary>  
  /// 定义一个服务对象  
  /// </summary>  
  private ServiceHost _myHelloHost;
  //private const string _host = "net.pipe://localhost"; 
  //private const string _host = "net.pipe://127.0.0.1"; 
  private const string _host = "net.pipe://10.128.42.223"; 
  private const string _path = "/Hello";
  private static readonly Binding _binding = new NetNamedPipeBinding(); //服务定义一个绑定  
  private static readonly Type _contract = typeof(IHelloService);  //服务契约接口  
  private static readonly Type _service = typeof(HelloService);  //服务契约实现类型  

  public const string Address = _host   _path;

  public MyHelloHost()
  {
    CreateHelloServiceHost();
  }
  /// <summary>  
  /// 构造服务对象  
  /// </summary>  
  protected void CreateHelloServiceHost()
  {
    _myHelloHost = new ServiceHost(_service, new Uri[] { new Uri(_host) });//创建服务对象  
    _myHelloHost.AddServiceEndpoint(_contract, _binding, _path); //添加终结点  
  }
  /// <summary>  
  /// 运行服务
  /// </summary>  
  public void Open()
  {
    Console.WriteLine("Hello service starting ...");
    _myHelloHost.Open();
    Console.WriteLine("Hello service running ...");
  }
  public void Dispose()
  {
    if (_myHelloHost != null)
      (_myHelloHost as IDisposable).Dispose();
  }
}

新建客户端调用程序

添加项目引用HelloService和HelloServiceHost,引用之前的类库项目。

HelloClient项目中Program.cs代码如下:

代码语言:javascript复制
using (HelloProxy proxy = new HelloProxy())
{
  //利用代理调用方法  
  Console.WriteLine(proxy.Say("nestor liu"));
  Console.ReadLine();
}

HelloProxy类如下:

代码语言:javascript复制
public class HelloProxy : ClientBase<IHelloService>, IService
{
  public static readonly Binding HelloBinding = new NetNamedPipeBinding();  //硬编码定义绑定  
                                        //硬编码定义地址 注意:这里要和之前服务定义的地址保持一直  
  public static readonly EndpointAddress HelloAddress = new EndpointAddress(new Uri(MyHelloHost.Address));
  public HelloProxy() : base(HelloBinding, HelloAddress) { } //构造方法  

  public string Say(string name)
  {
    //使用Channel属性对服务进行调用  
    return Channel.SayHello(name);
  }
}

IService接口和服务端定义服务契约是一致的:

代码语言:javascript复制
[ServiceContract]
public interface IService
{
  [OperationContract]
  string Say(string name);
}

先运行HelloServiceHost

然后运行HelloClient

运行结果如下:

0 人点赞