【问题标题】:Polymorphism in WCFWCF 中的多态性
【发布时间】:2009-03-25 13:22:43
【问题描述】:

我正在考虑构建一个可以存储/检索一系列不同类型的 WCF 服务。 以下示例是否可行并且也被认为是可接受的设计:

[ServiceContract]
public interface IConnection
{        
   [OperationContract]
    IObject RetrieveObject(Guid ObjectID); 

   [OperationContract]
    Guid StoreObject(IObject NewObject); 


}

[ServiceContract]
[ServiceKnownType(IOne)]
[ServiceKnownType(ITwo)]
public interface IObject
{
    [DataMember]
    Guid ObjectID;

}

[ServiceContract]
public interface IOne:IObject
{
    [DataMember]
    String StringOne;

}

[ServiceContract]
public interface ITwo:IObject
{
    [DataMember]
    String StringTwo;

}

使用该服务时,我需要能够将子类型传递给 StoreObject 方法,并从 RetrieveObject 方法将它们作为子类型返回。

有更好的选择吗?

谢谢, 抢

【问题讨论】:

    标签: c# wcf polymorphism


    【解决方案1】:

    您的示例将无法编译,因为接口不能包含字段,即 ObjectID、StringOne 和 StringTwo。您尝试使用 IObject、IOne 和 ITwo 定义的是数据合同,而不是服务合同。因此,您应该使用 DataContract 属性,而不是 ServiceContract 属性和类,而不是接口。

    [DataContract]
    [KnownType(typeof(MyOne))]
    [KnownType(typeof(MyTwo))]
    public class MyObject
    {
        [DataMember]
        Guid ObjectID;
    }
    [DataContract]
    public class MyOne : MyObject
    {
        [DataMember]
        String StringOne;
    }
    [DataContract]
    public class MyTwo : MyObject
    {
        [DataMember]
        String StringTwo;
    }
    

    请注意,这些是类,而不是接口。 DataContract 属性已替换 ServiceContract 属性。 KnownType 属性已替换 ServiceKnownType 属性。从我所看到的来看,这更规范。

    您的服务合同将被定义如下:

    [ServiceContract]
    public interface IConnection
    {
        [OperationContract]
        [ServiceKnownType(typeof(MyOne))]
        [ServiceKnownType(typeof(MyTwo))]
        MyObject RetrieveObject(Guid ObjectID);
    
        [OperationContract]
        [ServiceKnownType(typeof(MyOne))]
        [ServiceKnownType(typeof(MyTwo))]
        Guid StoreObject(MyObject NewObject);
    }
    

    您可以将 ServiceKnownType 属性放在合同级别(即,在 ServiceContract 属性下方),以使其适用于合同的所有操作。

    [ServiceContract]
    [ServiceKnownType(typeof(MyOne))]
    [ServiceKnownType(typeof(MyTwo))]
    public interface IConnection
    {
        [OperationContract]
        MyObject RetrieveObject(Guid ObjectID);
    
        [OperationContract]
        Guid StoreObject(MyObject NewObject);
    }
    

    可以在数据合同中使用如下接口:

    interface IEmployee
    {
        string FirstName
        { get; set; }
        string LastName
        { get; set; }
    }
    [DataContact]
    class Employee : IEmployee
    {...}
    

    但是,导出的元数据中不包含 IEmployee 接口。因此,如果您使用 svcutil 生成代理类,您的客户将不会知道 IEmployee。如果您的服务和客户端驻留在同一个应用程序中,这没什么大不了的(这是在应用程序域之间进行通信的好方法)。但是,如果您的客户端与您的服务是分开的(在绝大多数情况下,它将是),这将成为问题,因为您必须在客户端手动复制 IEmployee 接口。

    【讨论】:

    • 您可以举一个具体的例子来说明如何通过 WCF 使用您提到的 IEmployee 接口吗?
    • @Matt Davis,缺少一件事 :) 也许是一些 xml?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-01
    • 2016-03-19
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    • 2011-11-29
    • 2011-02-16
    相关资源
    最近更新 更多