• 使用WCF进行跨平台开发之一(WCF的实现、控制台托管与.net平台的调用)


         WCF是Windows Communication Foundation的缩写,是微软发展的一组数据通信的应用程序开发接口,它是.NET框架的一部分,是WinFx的三个重要开发类库之一,其它两个是WPF和WF。在本系列文章

    (我现在计划的应该是三篇,一篇WCF的开发和部署,另外是在.net平台上调用它,第二篇是PHP调用,第三篇是JAVA调用)。

         在本次的跨平台集成通信开发示例中,使用到的各种技术,咱且走且看,一边开发一边讲解。

    1.创建项目结构

    使用VS2010一个名为IntergatedCommunication的空解决方案,在其下,新建Contracts、Implemention两个类库项目,分别为契约的设计与服务的实现,而后新建ConsoleHost、Client两个控制台应用程序,分别为在控制台中实现服务托管使用,一个作为.net平台上调用WCF的实例使用,如下图

    image

    2.契约的设计

         本实例我还是想让它确实可以应用在实际项目中,所以我在设计的时候,将使用复杂类型(complex type),因为这并不同于普通类型,尤其在java和php在使用复杂类型参数是,调用方法是很不一样的。

         首先对Contracts、Implemention和ConsoleHost项目中添加对System.ServiceModel和System.Runtime.Serialization的引用。这两个命名空间中包含ServiceContractAttribute等WCF需要的契约特性类,和对复杂类型序列化的类DataContractSerializer。

    image

         本示例使用员工信息(员工ID、员工姓名、所属部门)查询本员工上月的工资明细(员工ID、薪水、日期),所以首先建立两个类Employee类和SalaryDetail类,在类中引用System.Runtime.Serialization命名空间,并且,在类上添加DataContractAttribute并在每个类属性上添加DataMemberAttribute:

    Employee.cs

    using System.Runtime.Serialization;
     
    namespace Contracts
    {
        [DataContract]
        public class Employee
        {
            [DataMember]
            public string Id { get; set; }
            [DataMember]
            public string Name { get; set; }
            [DataMember]
            public string Department { get; set; }
        }
    }
     
     
    SalaryDetail.cs
    using System.Runtime.Serialization;
     
    namespace Contracts
    {
        [DataContract]
        public class SalaryDetail
        {
            [DataMember]
            public string Id { get; set; }
            [DataMember]
            public decimal Salary { get; set; }
            [DataMember]
            public DateTime Date { get; set; }
        }
    }
     
    以上所设计的是数据契约,在使用DataContract和DataMember修饰和类和属性后,可将这些类型和属性暴露在元数据中,而后设计服务契约
         定义一个借口名为IEmployeeManagement并添加一个方法签名GetSalaryOfLastMonth,并添加ServiceContractAttribute和OperationContractAttribute。
        IEmployeeManagement.cs
    using System.ServiceModel;
     
    namespace Contracts
    {
        [ServiceContract]
        public interface IEmployeeManagement
        {
            [OperationContract]
            SalaryDetail GetSalaryOfLastMonth(Employee emp);
        }
    }

    3.实现服务

        在Implemention中添加对Contracts项目的引用,添加EmployeeManagement类,实现IEmployeeManagement接口

    EmployeeManagement.cs

    using Contracts;
     
    namespace Implemention
    {
        public class EmployeeManagement:IEmployeeManagement
        {
            public SalaryDetail GetSalaryOfLastMonth(Employee emp)
            {
                SalaryDetail salaryDetail = new SalaryDetail();
                salaryDetail.Id = emp.Id;
                salaryDetail.Date = DateTime.Now.AddMonths(-1);
                salaryDetail.Salary = 20000;
                return salaryDetail;
            }
        }
    }
     
    因为这里实现的内容并不重要,所以没有具体的去实现它,知识简单的返回了一个SalaryDetail的实例,Id为传入参数的员工ID,时间为当前时间的前一个月,薪水为固定的20000。
     

    4.控制台托管服务

         在ConsoleHost中添加对以上两个项目的引用,这时,生成整个解决方案,然后在ConsoleHost中添加应用程序配置文件App.config。并使用WCF服务配置编辑器打开它,并配置服务托管地址和绑定类型等信息,最终配置结果为

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <system.serviceModel>
            <behaviors>
                <serviceBehaviors>
                    <behavior name="ExposeMetaDataBehavior">
                        <serviceMetadata httpGetEnabled="true" httpGetUrl="EmployeeManagement/MEX" />
                    </behavior>
                </serviceBehaviors>
            </behaviors>
            <services>
                <service behaviorConfiguration="ExposeMetaDataBehavior" name="Implemention.EmployeeManagement">
                    <endpoint address="EmployeeManagement"
                        binding="wsHttpBinding" bindingConfiguration="" contract="Contracts.IEmployeeManagement" />
                  <host>
                    <baseAddresses>
                      <add baseAddress="http://localhost:9876/"/>
                    </baseAddresses>
                  </host>
                </service>
            </services>
        </system.serviceModel>
    </configuration>

    打开program.cs,在main方法中添加代码,托管服务

    using System.ServiceModel;
    using Implemention;
     
    namespace ConsoleHost
    {
        class Program
        {
            static void Main(string[] args)
            {
                ServiceHost host = new ServiceHost(typeof(Implemention.EmployeeManagement));
                try
                {
                    Console.WriteLine("EmployeeManagement Service Starting");
                    host.Open();
                    Console.WriteLine("EmployeeManagement Service Started");
                    Console.ReadKey();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    if (ex.InnerException != null)
                    {
                        Console.WriteLine("\n" + ex.InnerException.Message);
                    }
                }
                finally
                {
                    host.Close();
                }
                Console.ReadKey();
            }
        }
    }

    生成解决方案,并在VS外以管理员权限启动ConsoleHost.exe文件,这样就在控制台中托管了服务

    5.在.net平台中调用WCF

    在Client中,添加服务引用,命名空间设置为ServiceReference

    image

    在program.cs中添加代码,调用控制台中托管的服务

    namespace Client
    {
        class Program
        {
            static void Main(string[] args)
            {
                ServiceReference.EmployeeManagementClient client = new ServiceReference.EmployeeManagementClient();
                ServiceReference.Employee emp = new ServiceReference.Employee() { Id = "dev001", Name = "James White", Department = "Development" };
                ServiceReference.SalaryDetail salaryDetail = client.GetSalaryOfLastMonth(emp);
                Console.WriteLine("Employee number {0}'s salary of {1} month is ¥{2}", salaryDetail.Id, salaryDetail.Date.Month, salaryDetail.Salary);
                Console.ReadKey();
            }
        }
    }

    image

    在这里,我们已经简单的实现了WCF服务的实现和.net本平台调用WCF,这一篇不是最重要的,下一篇是使用IIS托管WCF并使用PHP调用WCF。

  • 相关阅读:
    双边沿采样
    `ifdef、`else、`endif 用法
    交通信号灯
    异步复位同步释放
    用Verilog来实现d触发器2分频的Verilog hdl程序
    谈谈Mux与门电路的相互替换(包含实例分析)
    数字电路笔试题
    仰视奶牛
    单调栈
    div2 620 C
  • 原文地址:https://www.cnblogs.com/xiaoyaojian/p/2752652.html
Copyright © 2020-2023  润新知