WCF 快到碗里来: 1、我是谁

本文将介绍下WCF的基本知识,包括WCF能够做什么、为什么要用WCF等,并在最后展示一个最简单的WCF例子来结束全文。关于WCF更高阶的东东,敬请期待~~


什么是WCF?

它是一种面向服务架构(SOA)的,用于通信的技术。


什么时候需要进行通信?

这个通信其实就是指两个应用程序之间的交流,比如我们手机上查天气的app就需要与服务器进行通信 (“Hey, 服务器君,告诉我现在宁波的天气!”,“好的,App君,宁波的天气现在晴朗~”)。


还有其它通信技术吗?

当然有,管道、Socket、Web Service、.Net remoting、MSMQ 等等。


为什么要用WCF?

除 WCF 之外的每种通信技术都有各自擅长的领域,比如命名管道适合同一台机器不同.Net应用程序之间的通信,而 Remoting 适合不同机器 .Net 应用程序之间的通信,Web Service 则适合不同机器、不同平台、不同语言的应用程序之间的通信等。这些通信技术各有所长,只有在最适合的时候才能发挥出最佳的性能,试想如果用 Web service 去完成同一台机器两个 .Net 应用程序间的通信,将是一种多大的浪费。这就好像两个人面对面,却要用手机进行互相沟通一样。

这么多通信技术对于开发人员来说并不是好事,因为每种通信技术都相当于一本独立的武学秘籍,想要掌握不同的通信技术就要修炼不同的武学秘籍,这怎是一个 “惨” 字了得~~

有鉴于此,WCF就顺势出现了。它像吸星大法一样把几乎所有.Net的通信技术都融合到了自己的技术下,换句话说,当你修炼完WCF时,就相当于修炼了上述这些不同的通信技术。你只需要学习一种内功,就能掌握所有这些通信招式~  


但在修炼之前,还必须问自己一下,你的项目现在或未来可能存在多种通信环境吗?如果永远只有一种,那么就别用 WCF 了~


欲炼此功,必先....

想多了的,请举手~ 

WCF 是微软在 2006 年推出的 .Net Framework 3.0 中的一部分,3.0 使用的仍然是上一代 2.0 的框架,只是在此基础上增加了 WCF、WPF、WF 和 WCS。所以欲炼此功,必先安装 .Net Framework 3.0,当然你其实只需要安装 Visual Studio 2005 或以上版本都可以进行 WCF 的开发。

Showtime

说了这么多,各位肯定烦了,下面就给大伙展示一个最简单的例子,在以后的文章中会对这个例子进行不断的完善,并最终实现一个安全可靠且能由多种终端访问的家用记账小软件。

本文的例子很简单,最后实现的功能是一个C/S程序,先来看最终的效果:


上面这个例子很简单,客户端会将钱存入服务器端,然后通过 “刷新” 就能看到最新的存款。


解决方案

解决方案中一共建立4个项目:Contract(契约)、Service(服务)、Host(宿主)、Client(客户端)。其中服务是对契约的实现,服务需要宿主才能运行。为了便于理解 WCF 的实质,这里全部采用最普通的项目进行构建。Contract 和 Service 均为普通的类库项目,Host 为控制台项目,Client 为 Winform 项目。

解决方案


Contract

契约是WCF的重要组成部分,相当于提供了服务双方进行沟通的约定。这是一个类库,需要引入 “System.ServiceModel” 程序集。之所以独立作为一个类库项目而不是和Service放在同一个项目中,是为了便于之后将这部分分发给客户端,而不至于泄漏真实的逻辑。

    [ServiceContract]
    public interface IMoneyService
    {
        /// <summary>
        /// 存钱
        /// </summary>
        /// <param name="money"></param>
        /// <returns></returns>
        [OperationContract]
        decimal Deposit(decimal money);

        [OperationContract]
        decimal GetTotal();
    }

上面其实就是个很普通的接口定义。通过加上 ServiceContract 和 OperationContract 特性来告诉 WCF 这些是可被客户端调用的。


Service

服务也很简单,只需要对上述接口简单实现便可。

    public class MoneyService : IMoneyService
    {
        //模拟数据库
        private static decimal _totalMoney = 0;

        public decimal Deposit(decimal money)
        {
            _totalMoney += money;
            return _totalMoney;
        }

        public decimal GetTotal()
        {
             return _totalMoney;
        }
    }

上面的代码很简单吧!


Host

WCF中的服务只有被放在宿主中才能正常发挥功能,宿主可以是普通的控制台项目,也可以是 IIS、Windows 服务、Winform 等其它类型的。放在IIS和Windows 服务中的好处就是不需要手动启动,只要Windows操作系统启动,便能自动开始提供服务。

    static void Main(string[] args)
    {
        using (ServiceHost host = new ServiceHost(typeof(MoneyService)))
        {
            host.AddServiceEndpoint(typeof(IMoneyService), new BasicHttpBinding(), "http://localhost:9999/");
            host.Opened += delegate { Console.WriteLine("Host is running"); };
            host.Closed += delegate { Console.WriteLine("Host is stopped"); };

            host.Open(); //启动宿主
            Console.ReadLine();
            host.Close();
        }
    }

淘宝就相当于是宿主,所有其上的店铺都可以认为是一个个服务。当开了一个淘宝店铺之后,店小二只有将店铺的地址公布出去,消费者才有可能到你店里来。这个和宿主是一个道理,想让这个宿主提供服务,必须把服务的地址暴露出去,本例中的 "http://localhost:9999" 就是用于表示 IMoneyService 这个服务的地址。光有地址就行了吗?我们在淘宝上买宝贝的时候,有时候还要考虑这个商品的运输方式,是用申通、EMS 还是顺风呢?宝贝在出货前要不要加固呢?这些其实都是 Binding 所考虑的问题,如本例中的 basicHttpBinding 就意味着使用最基本的 Http 传输协议进行消息的传输,且不采用任何安全措施(整个消息传输是明文传输,所以网络上的黑客可以轻易截获其中的消息)。这三个内容最终构成了 EndPoint,即终结点,这也是 WCF 中的重要组成部分。


Client

消费者要到你的店铺来,就必须要知道你的地址,想要消费你的宝贝,你和店小二就必须就运输方式、包装等达成一致的意见。

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        ChannelFactory<IMoneyService> _factory;
        IMoneyService _srv;

        private void Form1_Load(object sender, EventArgs e)
        {
            _factory = new ChannelFactory<IMoneyService>(new BasicHttpBinding(), "http://localhost:9999/");
            _srv = _factory.CreateChannel();
        }

        private void btnDeposit_Click(object sender, EventArgs e)
        {
            _srv.Deposit(numDeposit.Value);
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            lblDeposit.Text = _srv.GetTotal().ToString();
        }
    }

上面的代码中, ChannelFactory 通过传入的 Binding 和 地址 与服务提供者建立了一条通道(这个 Binding 和 地址必须与服务端的一致),然后就能通过一个服务代理调用所有服务了。


源代码管理

MoneyManagement


总结

本文简单介绍了 WCF 是什么,为什么要使用 WCF,并在最后通过一个简单的例子演示了如何搭建一个 WCF 项目。下篇文章中,我将会讲解下 WCF 中的几个关键知识点。

文章索引

[隐 藏]

本站采用知识共享署名 3.0 中国大陆许可协议进行许可。 ©2014 Charley Box | 关于本站 | 浙ICP备13014059号