WCF-使用几乎相同的数据合同的多个服务合同

| 我对WCF专家有一个新问题。 因此,我有一个类
User
,它很接近用于数据库操作的DB的\'User \'表示形式。现在,我想有两个使用该类作为数据契约的不同服务契约,但是每个契约都有自己的方式……我的意思是,
public class DBLayer
{
    void InsertUsers(List<User> userList)
    {
        // both \'PropertyVisibleForService1\' and \'PropertyVisibleForService2\'
        // are used HERE to be inserted into their columns 
    }
}

[DataContract]
public class User
{
  [DataMember] public string PropertyVisibleOnlyForService1{...}
  [DataMember] public string PropertyVisibleOnlyForService2{...}
}

[ServiceContract]
public interface IService1  
{   
   List<User> GetUsers();  // user with \'PropertyVisibleOnlyForService1\' inside
}

[ServiceContract]
public interface IService2  
{   
    List<User> GetUsers(); // user with \'PropertyVisibleOnlyForService2\' inside 
}
因此,我们的想法是每个服务将获得不同类型的用户,即“ 2”的子集。请记住,我想像使用DB2操作一样使用ѭ2,,实现这一目标的选择是什么?我是否真的需要创建其他数据合同,或者还有另一种更聪明的方法? 最好的办法不仅是为我提供解决方案,而且还要向我解释一些最佳实践和替代方法。 先感谢您。 编辑1: 我在此处添加了一个虚拟DBLayer类,以获取更好的概述以及为什么我认为在这种情况下继承可能不好。 一种解决方案是将另一个\'4'\'和\'5'\\作为数据协定,这些合同将在末尾从\'0'映射到\'
User
\',但我想要其他一些观点。 EDIT2:非常好的文章在这种情况下对我有帮助:http://bloggingabout.net/blogs/vagif/archive/2009/03/29/iextensibledataobject-is-not-only-for-backward-compatibility.aspx     
已邀请:
您可以为每种服务创建单独的DTO,但是您的案例实际上是Decorator模式的理想选择:
[DataContract]
public class UserForService1 : User
{
     private User mUser;
     public UserForService1(User u)
     {
         mUser = u;
     }

     //expose only properties you\'d like the user of this data contract to see
     [DataMember]
     public string SomeProperty
     {
         get
         {
            //always call into the \'wrapped\' object
            return mUser.SomeProperty;
         }
         set
         {
            mUser.SomeProperty = value;
         }
     }
     // etc...
}
对于Service2类似的代码,仅显示您在此关心的内容...     
如果它们旨在代表不同类型的用户,则它们应该是不同的类。我同意phoog的评论,您应该从共享的User类派生想要的类型,并将特定的服务属性添加到派生的类。 您为什么不认为继承在这种情况下会很好?如果您提供更多详细信息,我们可以尝试修改建议以适合您的实际问题。     
如注释中所建议,您可以从基本用户派生两个类,然后使用“数据协定已知类型”来实现所需的目标。有关更多示例,请参见以下链接。 http://www.freddes.se/2010/05/19/wcf-knowntype-attribute-example/ http://footheory.com/blogs/bennie/archive/2007/07/28/handling-data-contract-object-hierarchies-in-wcf.aspx     
如果您不想使用继承,则类似:
[DataContract]
public class User
{
}

[DataContract]
public class Service1User : User
{
  [DataMember] public string PropertyVisibleOnlyForService1{...}
}

[DataContract]
public class Service2User : User
{
  [DataMember] public string PropertyVisibleOnlyForService2{...}
}

[ServiceContract]
public interface IService1  
{   
   List<Service1User> GetUsers();  // user with \'PropertyVisibleOnlyForService1\' inside
}

[ServiceContract]
public interface IService2  
{   
    List<Service2User> GetUsers(); // user with \'PropertyVisibleOnlyForService2\' inside 
}
那我不确定你会怎么做。此时,您的排序违反了类型声明的原则。以正常的.NET方式考虑它;如果您在应用程序中定义\“ User \”,则它在各处都是相同的类型。某些属性无法从某些其他类或方法中隐藏。 WCF还打算将此类型信息打包到生成的WSDL中,并且只定义一次User类型,因此它需要知道那里的属性。 现在,如果您关心的只是构造的实际SOAP消息,而不关心WSDL或从WSDL生成的任何客户端将看到的内容,那么从技术上讲,您可以使它不将该属性发送到SOAP中消息为空时,通过执行以下操作:
    [DataMember(EmitDefaultValue=false)]
然后,当该属性为null时,它将不会包含在序列化中。但是,如果客户端是从WSDL生成的,那将没有什么真正的区别,因为它的用户类型仍然必须包含两个属性。它只会更改序列化,而不是发送诸如以下内容的客户端:
<User>
  <PropertyVisibleOnlyForService1 nil=\"true\" />
  <PropertyVisibleOnlyForService2>something</PropertyVisibleOnlyForService2>
</User>
它会发送:
<User>
  <PropertyVisibleOnlyForService2>something</PropertyVisibleOnlyForService2>
</User>
    

要回复问题请先登录注册