自托管Self Hosting
如果是web服务,我们只能将服务托管在IIS上,但是WCF提供了让服务可以托管在任何应用程序(比如控制台应用程序,Windows Form等等)中的能力。许多有趣开发者有责任提供和管理托管进程的生命周期。服务端和客户端可以同时存在在相同的进程中。现在,让我们创建一个托管在控制台应用程序中的WCF服务。我们将会以抽象类ClientBase为基类创建一个代理。
Note:托管程序必须在客户端访问之前运行,这也意味着你得预启动它。
Step1: 让我们从创建服务七月和它的实现开始吧。创建一个控制台应用程序,并且命名为MyCalculatorService。这是一个简单的服务,它只是返回两个数想加的和。
Step 2: 添加System.ServiceModel引用
Step 3: 创建ISimpleCalculator接口,加入ServiceContract和OperationContract到类和方法上,你会在随后的内容中了解它们的作用。这些Attribute将会把服务公布给调用方。
IMyCalculatorService.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace MyCalculatorService { [ServiceContract()] public interface ISimpleCalculator { [OperationContract()] int Add(int num1, int num2); } }
Step 4: 如下所示,MyCalculatorService是IMyCalculatorService接口的实现类
MyCalculatorService.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyCalculatorService { class SimpleCalculator : ISimpleCalculator { public int Add(int num1, int num2) { return num1 + num2; } } }
Step 5: 现在服务已经准备好了,让我们开始实现托管进程吧,创建一个新的控制台应用程序MyCalculatorServiceHost
Step 6: ServiceHost是托管WCF服务的核心类。它的构造函数可以接受已经实现了的契约类和服务地址作为参数,你可以用逗号分隔注册多个基地址,但是地址必须基于同样的传输协议(http等)
Uri httpUrl = new Uri("http://localhost:8090/MyService/SimpleCalculator"); Uri tcpUrl = new Uri("net.tcp://localhost:8090/MyService/SimpleCalculator"); ServiceHost host = new ServiceHost(typeof(MyCalculatorService.SimpleCalculator), httpUrl, tcpUrl);
使用AddServiceEndpoint()可以加入多个终结点。host.Open()将启动服务,之后就可以为客户端提供服务了。
Step 7: 以下程序说明了如果实现托管进程
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Description; namespace MyCalculatorServiceHost { class Program { static void Main(string[] args) { //Create a URI to serve as the base address Uri httpUrl = new Uri("http://localhost:8090/MyService/SimpleCalculator"); //Create ServiceHost ServiceHost host = new ServiceHost(typeof(MyCalculatorService.SimpleCalculator), httpUrl); //Add a service endpoint host.AddServiceEndpoint(typeof(MyCalculatorService.ISimpleCalculator) , new WSHttpBinding(), ""); //Enable metadata exchange ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); smb.HttpGetEnabled = true; host.Description.Behaviors.Add(smb); //Start the Service host.Open(); Console.WriteLine("Service is host at " + DateTime.Now.ToString()); Console.WriteLine("Host is running... Presskey to stop"); Console.ReadLine(); } } }
Step 8: 服务一旦被托管启动,我们就可以创建为客户端服务的带来类了,创建代理有不同的方法
1.使用SvcUtil.exe创建代理以及相关联的配置文件
2.将服务引用添加到客户端程序
3.实现基类ClientBase
在这些方法中,实现ClientBase
MyCalculatorServiceProxy.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using MyCalculatorService; namespace MyCalculatorServiceProxy { public class MyCalculatorServiceProxy : //WCF create proxy for ISimpleCalculator using ClientBase ClientBase, ISimpleCalculator { public int Add(int num1, int num2) { //Call base to do funtion return base.Channel.Add(num1, num2); } } }
Step 9: 在客户端,我们创建代理类的实例,并且使用如下的方法调用,将代理dll的参照加入到这个工程中。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace MyCalculatorServiceClient { class Program { static void Main(string[] args) { MyCalculatorServiceProxy.MyCalculatorServiceProxy proxy ; proxy= new MyCalculatorServiceProxy.MyCalculatorServiceProxy(); Console.WriteLine("Client is running at " + DateTime.Now.ToString()); Console.WriteLine("Sum of two numbers... 5+5 ="+proxy.Add(5,5)); Console.ReadLine(); } } }
Step 10 : 终结点信息需要被加入到客户端程序的配置文件中。
Step 11: 运行客户端之前,你需要先启动服务端,客户端的输出如下所示。
自托管展现了in-Pro hosting的好处。以编程的方式访问,并且可以编程为单例服务。我系统你会喜欢上自托管的方式,现在让我们进入下一步,将服务托管在Windows Activation service中。