WCF相关的许多类型都位于System.ServiceModel中,因此需要先引用进来
- 创建一个控制台应用程序,定义服务接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
namespace wcf
{
[ServiceContract(Namespace = "demo", Name = "demo")]
interface IDemo
{
[OperationContract]
int add(int a, int b);
void run();
}
}
要使接口被当做服务接口被公开,需要在接口上加上ServiceContract特性,在服务协定接口需要用OperationContract来标记操作协定,没有这个标记,操作协定将不会被公开,客户端将无法调用。
- 定义一个类,实现服务协定接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace wcf
{
class Demo:IDemo
{
public int add(int a, int b)
{
return a + b;
}
public void run()
{
}
}
}
- 创建ServiceHost实例,寄宿wcf服务
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
namespace wcf
{
class Program
{
static void Main(string[] args)
{
Uri uri = new Uri("http://localhost:500");
using (ServiceHost serviceHost = new ServiceHost(typeof(Demo), uri))
{
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
serviceHost.AddServiceEndpoint(typeof(IDemo), basicHttpBinding, "demo");
serviceHost.Open();
Console.Read();
}
}
}
}
在实例化servicehost类时,需要传递一个表示服务实现类的Type作为参数,注意此处的Type类型是实现了服务协定接口的类。服务的终结点用来向客户端公开WCF服务,他需要指定一个有效的地址,本例中指定相对路径demo,结合传递给ServiceHost类构造函数的地址,该服务终结点的地址变为http://localhost:500/demo.调用open方法打开服务,客户端就可以访问了。
- 使用通道工厂访问WCF服务
下面的代码将使用通道工厂完成一个实现加法的WCF服务
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
namespace client
{
class Program
{
static void Main(string[] args)
{
Uri uri = new Uri("http://localhost:500/demo");
EndpointAddress eaddr = new EndpointAddress(uri);
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
Itest itest = ChannelFactory<Itest>.CreateChannel(basicHttpBinding, eaddr);
int a = itest.add(3, 5);
Console.WriteLine(a.ToString());
Console.ReadKey();
itest.Close();
}
}
}
其中客户端需要重新声明协定接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
namespace client
{
[ServiceContract(Namespace ="demo",Name ="demo")]
interface Itest:IClientChannel
{
[OperationContract]
int add(int a, int b);
}
}
由于服务器上服务协定接口的名字是IDemo,与客户端的接口名称不一致,这种情况下双方无法进行通讯,但是客户端与服务端设置了相同的Namespace以及Name属性后,就可以通讯了