我正在寻找构建可以存储/检索一系列不同类型的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方法中将它们作为其Child类型返回.
有更好的选择吗?
谢谢,罗布
您的示例将无法编译,因为接口不能包含字段,即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接口.