WCF学习笔记(三)使用(Service)KnownType标记实现继承、多态特性

1.服务器端:

///


    /// 实现IExtensibleDataObject接口,表示这个类的派生类也可以序列化
    /// IsRequired表示该属性是否需要赋值之后才能序列化
    ///
    /// 注意:此类上没有标记KnownType属性,于是在客户端找不到School的派生类
    /// 若是在此类上没有KnownType标记,在契约接口上使用ServiceKnownType标记也是可以的
    /// 当然,ServiceKnownType标记也是可以应用在接口里面的方法上面的
    ///

    [DataContract(Name = "SchoolEntity", Namespace = "http://schemas.yoyo/zhu")]
    //[KnownType(typeof(Teacher))]
    //[KnownType(typeof(Student))]
    public class School : IExtensibleDataObject
    {
        ///
        /// 学校编号
        ///

        [DataMember(Name = "Num", IsRequired = true, Order = 0)]
        public string s_Num { get; set; }
        ///
        /// 学校名称
        ///

        [DataMember(Name = "Name", IsRequired = true, Order = 1)]
        public string s_Name { get; set; }
        ///
        /// 描述
        ///

        [DataMember(Name = "Description", IsRequired = false, Order = 2)]
        public string s_Description { get; set; }


        private ExtensionDataObject extensionDataObject;

        #region IExtensibleDataObject 成员

        public ExtensionDataObject ExtensionData
        {
            get
            {
                return extensionDataObject;
            }
            set
            {
                extensionDataObject = value;
            }
        }

        #endregion
    }

派生类:

    [DataContract(Namespace = "http://schemas.yoyo/zhu")]
    public class Student : School
    {
        public Student()
        {
            this.s_SchoolDerivedClass = SchoolEnmu.Student;
        }
    }

    [DataContract(Namespace = "http://schemas.yoyo/zhu")]
    public class Teacher : School
    {
        public Teacher()
        {
            this.s_SchoolDerivedClass = SchoolEnmu.Teacher;
        }
    }

2.契约

    [ServiceContract(Name = "IKonwTypeService", Namespace = "http://www.yoyo/zhu")]
    [ServiceKnownType(typeof(Teacher))]
    [ServiceKnownType(typeof(Student))]
    public interface IKonwTypeService
    {
        [OperationContract]
        void AddTeacher(School sc);
        [OperationContract]
        List GetTeacher();
    }

    //这个ServiceBehavior可有可无
    //[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    public class KonwTypeService : IKonwTypeService
    {
        private static School school;
        #region IKonwTypeService 成员

        public void AddTeacher(School sc)
        {
            school = sc;
        }

        public List GetTeacher()
        {
            List list = new List();
            list.Add(school);
            return list;
        }

        #endregion
    }

3.宿主环境配置:

           ServiceHost host = new ServiceHost(typeof(KonwTypeService));
            host.Open();
            Console.WriteLine("宿主服务已启动!");
            Console.ReadKey();

 
   
     
       
         
            http://localhost:8044"/
>
         
       
       
       
     
   
   
     
       
         
       

     

   

 

4.客户端(引用服务的方式见WCF学习笔记(二))

 

5.注意:当ServiceKnownType和KnownType标记都没使用时,可以在配置文件里面添加如下代码,在客户端也能生成其派生类


 
   
     
       
       
     

   

 

 

 

小结:

KnowType表示:在WCF中一个继承类可以转换成其父类,加上这个标签后,父类也可以转成子类,从而保留多态性。同时,客户端还不会生成子类的相应信息。
ServiceKnowType:当提供的服务中有参数是上面提及的父类,为了把这个父类的派生类带出来,于是需要在接口上面使用ServiceKnowType指定其派生类。当只需要在某个方法上面使用该父类的派生类,就可

以在该方法的上面使用ServiceKnowType指定即可。
在WCF中,继承的接口和类是反映不到客户端的,因此说WCF牺牲了OO的继承和多态的特性。但是这种特性可以使用已知类型的方式弥补。

 

源代码下载地址:http://download.csdn.net/detail/yoyoshaoye/3614453

你可能感兴趣的:(WCF)