在学习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
运行结果如下: