SOA的基本特性:
1.服务时自制的
2.依赖于开放的标准
3.支持跨平台
4.鼓励创建可组合的服务
5.鼓励服务的复用
6.强调松耦合
WCF是对现有Windows平台下分布式通信技术的整合。过去几年比较典型的分布式通信技术有COM/DCOM,Enterprise Service,.NET Remoting,XMLWeb服务,MSMQ等。
建立一个简单的WCF应用
用VS2008新建四个项目,Contracts,Services,Hosting,Client.
Contracts 类库项目
using System.ServiceModel; namespace Danye.WcfServices.Contracts { [ServiceContract(Name="CalculatorServices",Namespace="http://mywinxp.vicp.net")] public interface ICalculator { [OperationContract] double Add(double x, double y); [OperationContract] double Subtract(double x, double y); [OperationContract] double Multiply(double x, double y); [OperationContract] double Divide(double x, double y); } }
Services类库项目
using Danye.WcfServices.Contracts; namespace Danye.WcfServices.Services { public class CalculatorServices: ICalculator { #region ICalculator 成员 public double Add(double x, double y) { return x + y; } public double Subtract(double x, double y) { return x - y; } public double Multiply(double x, double y) { return x * y; } public double Divide(double x, double y) { return x / y; } #endregion } }
Host类库项目
using System; using System.ServiceModel; using System.ServiceModel.Description; using Danye.WcfServices.Contracts; using Danye.WcfServices.Services; namespace Danye.WcfServices.Hosting { class Program { static void Main(string[] args) { using (ServiceHost host = new ServiceHost(typeof(CalculatorServices))) { host.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "http://127.0.0.1:9999/calculatorservice"); if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null) { ServiceMetadataBehavior behavior = new ServiceMetadataBehavior(); behavior.HttpGetEnabled = true; behavior.HttpGetUrl = new Uri("http://127.0.0.1:9999/calculatorservice/metadata"); host.Description.Behaviors.Add(behavior); } host.Opened += delegate { Console.WriteLine("CalculatorService已经启动,按任意键终止服务!"); }; host.Open(); Console.Read(); } } } }
上面是通过代码来host,很繁琐,通过配置工具来配置方便很多,打开vs2008
最后的File->另存为App.config 然后将此文件添加到Hosting中。
App.config代码
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="metedataBehavior"> <serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:9999/calculatorservice/metadata" /> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="metedataBehavior" name="Danye.WcfServices.Services.CalculatorServices"> <endpoint address="http://127.0.0.1:9999/calculatorservice" binding="basicHttpBinding" bindingConfiguration="" contract="Danye.WcfServices.Contracts.ICalculator" /> </service> </services> </system.serviceModel> </configuration>
运行下
发现报错,提示
HTTP 无法注册 URL http://+:9999/calculatorservice/。进程不具有此命名空间的访问权限(有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=70353)。
这是因为win7或vista权限问题,用管理员模式打开vs2008即可
接下来创建Client控制台项目,首先需要引入服务,在引入服务时,host必须运行着。
Client端代码如下:
using System; using Danye.WcfServices.Client.CalculatorServices; namespace Danye.WcfServices.Client { class Program { static void Main(string[] args) { using (CalculatorServicesClient proxy = new CalculatorServicesClient()) { Console.WriteLine("x+y={2}, when x={0} and y={1}", 1, 2, proxy.Add(1, 2)); Console.WriteLine("x-y={2}, when x={0} and y={1}", 1, 2, proxy.Subtract(1, 2)); Console.WriteLine("x*y={2}, when x={0} and y={1}", 1, 2, proxy.Multiply(1, 2)); Console.WriteLine("x/y={2}, when x={0} and y={1}", 1, 2, proxy.Divide(1, 2)); Console.Read(); } } } }
ok,上面是通过创建自动生成的,继承自ClientBase<T>的类型对象进行服务调用。
下面讲的是通过ChannelFactory<T>调用。
首先去除client的对服务的引用。右键删除。然后添加一个app.config配置文件,用wcf配置工具进行配置
保存即可
然后修改client端代码
using System; using System.ServiceModel; using Danye.WcfServices.Contracts; namespace Danye.WcfServices.Client { class Program { static void Main(string[] args) { using (ChannelFactory<ICalculator> channelFactory=new ChannelFactory<ICalculator>("calculatorservice") ) { ICalculator proxy = channelFactory.CreateChannel(); Console.WriteLine("x+y={2}, when x={0} and y={1}", 1, 2, proxy.Add(1, 2)); Console.WriteLine("x-y={2}, when x={0} and y={1}", 1, 2, proxy.Subtract(1, 2)); Console.WriteLine("x*y={2}, when x={0} and y={1}", 1, 2, proxy.Multiply(1, 2)); Console.WriteLine("x/y={2}, when x={0} and y={1}", 1, 2, proxy.Divide(1, 2)); Console.Read(); } } } }
Finally,讲的是host在IIS中。
在host在iis中,我碰到了个问题,总是提示
The type 'Danye.WcfServices.Services.CalculatorService', provided as the Service attribute value in the ServiceHost directive could not be found.
究其原因,主要是没认真看书上写的,要把生成的目录设置为bin,因为asp.net最后编译好的代码都在bin目录里
web.config代码
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="metadataBehavior"> <serviceMetadata httpGetEnabled="true" /> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="metadataBehavior" name="Danye.WcfServices.Services.CalculatorService"> <endpoint binding="basicHttpBinding" contract="Danye.WcfServices.Contracts.ICalculator" /> </service> </services> </system.serviceModel> <system.webServer> <directoryBrowse enabled="true" /> </system.webServer> </configuration>
CalculatorService.cs代码
using Danye.WcfServices.Contracts; namespace Danye.WcfServices.Services { public class CalculatorService: ICalculator { #region ICalculator 成员 public double Add(double x, double y) { return x + y; } public double Subtract(double x, double y) { return x - y; } public double Multiply(double x, double y) { return x * y; } public double Divide(double x, double y) { return x / y; } #endregion } }
%@ServiceHost Service="Danye.WcfServices.Services.CalculatorService"%
最后生成下就ok了
第一篇读书笔记完成了 ^_^~
下面是自我寄宿和通过iis寄宿的代码 http://files.cnblogs.com/danye/WcfServices_Self-Host.rar http://files.cnblogs.com/danye/WcfServices_IIS-Host.rar