自托管(Self-Hosting),就是由开发者提供和管理宿主进程的生命周期。自托管方式适用以下场景:需要确定客户端与服务端的进程(或机器)边界时;使用进程内托管,即服务与客户端处理相同的进程中时。自托管进程可以是控制台应用程序、Windows应用程序、Windows服务等,进程必须在客户端调用服务之前运行。
自托管支持通信的协议包括:HTTP、TCP、IPC、MSMQ。
自托管宿主进程必须在运行时显示地注册服务类型,同时为客户端的调用打开宿主,因此才要求宿主进程必须在客户端调用到达之前运行。创建宿主进程的方法通常是在Main() 方法中调用ServiceHost类。
下面我们通过一个DEMO来介绍自托管(Self-Hosting)。
开发环境:Visual Studio 2010 + Net Framework 4.0 。
1、创建一个WCf Service Library,主要代码如下:
namespace ServiceLibrary
{
//ServiceContract为服务契约
[ServiceContract(Namespace = "http://schemas.xinhaijulan.com/demos/SelfHost")]
public interface IHelloWCF
{
//OperationContract为方法契约
[OperationContract]
string GetMessage(string msg);
[OperationContract]
Item TestDataContract(Item item);
}
}
namespace ServiceLibrary
{
public class HelloWCF : IHelloWCF
{
public string GetMessage(string msg)
{
return string.Format("The server received message is : {0}", msg);
}
public Item TestDataContract(Item item)
{
if (item != null)
{
item.Name = "item from client is not null.";
}
else
{
item = new Item(0);
item.Name = "item from client is null.";
}
return item;
}
}
}
namespace ServiceLibrary
{
[DataContract(Name = "Item", Namespace = "http://schemas.xinhaijulan.com/demos/SelfHost")]
public class Item
{
public Item(int _id)
{
Id = _id;
}
[DataMember(Order = 0)]
public int Id { get; set; }
[DataMember(Order = 1)]
public string Name { get; set; }
}
}
以上为Service Library部分,为了实现启动服务端,我们需要显示注册服务类型。
2、创建Server控制台项目作为托管的进程项目,添加ServiceLibrary引用,主要代码如下:
namespace Server
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(ServiceLibrary.HelloWCF)))
{
host.AddServiceEndpoint(typeof(ServiceLibrary.IHelloWCF), new NetTcpBinding(), "net.tcp://localhost:9000/HelloWCF");
host.Open();
Console.WriteLine("Please input exit to close host.");
string key = Console.ReadLine();
while (key.ToLower() != "exit")
{
Console.WriteLine("Please input exit to close host.");
key = Console.ReadLine();
}
}
}
}
}
这里我们通过使用NetTcpBinding绑定,地址为:net.tcp://localhost:9000/HelloWCF,对于绑定与地址我们还可以配置在App.config文件中。
3、创建Client项目,添加ServiceLibrary引用,前面的项目我们都是通过添加Service 引用来调用服务端,这里我们通过代码的方式,来实现调用服务端。
/// <summary>
/// 测试ServiceLibrary
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
ChannelFactory<ServiceLibrary.IHelloWCF> channelFactory = new ChannelFactory<ServiceLibrary.IHelloWCF>(new NetTcpBinding());
ServiceLibrary.IHelloWCF client = channelFactory.CreateChannel(new EndpointAddress("net.tcp://localhost:9000/HelloWCF"));
Console.WriteLine("------------Begin-------------");
Console.WriteLine(client.GetMessage("Hello WCF!"));
ServiceLibrary.Item item = new ServiceLibrary.Item(1);
item = client.TestDataContract(item);
Console.WriteLine("item.Id:" + item.Id);
Console.WriteLine("item.Name:" + item.Name);
Console.WriteLine("------------End---------------");
Console.ReadLine();
}
因服务端使用NetTcpBinding绑定与端点地址:net.tcp://localhost:9000/HelloWCF,因此我们客户端创建调用对象时使用与服务端相同的绑定协议与地址。
4、启动服务端,右键Server->Debug->Start new instance 如下图:
5、启动客户端,右键Client->Debug->Start new instance,输出如下:
------------Begin-------------
The server received message is : Hello WCF!
item.Id:1
item.Name:item from client is not null.
------------End---------------
至此,本章一个自托管的DEMO介绍完毕,要点如下:
服务端使用Console Application来托管WCF进程ServiceHost;
服务端使用代码方式实现绑定与端点地址的编写(也可通过配置方式实现);
客户端通过代码方式实现服务端的调用;
客户端通过代码方式实现绑定与端点地址的编写,必须与服务端一致(也可通过配置方式实现);
服务端必须先启动,客户端方能调用服务端。
作者:心海巨澜
出处:http:xinhaijulan.cnblogs.com
版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。