[英]WCF - multiple service contracts using pretty same data contracts
我有一个关于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
}
因此,我们的想法是每个服务都会得到一个不同类型的用户,即'User'
子集。 请记住,我想使用'User'
作为数据库操作,我可以选择实现这一目标吗? 我真的需要创建不同的数据合同还是有另一种更聪明的方法?
最好不仅要给我解决方案,还要向我解释一些最佳实践和替代方案。
先感谢您。
EDIT1:我在这里添加了一个虚拟DBLayer类,以便更好地概述,以及为什么我认为在这种情况下继承可能不太好。
一个解决方案是将另一个' UserForService1
'和' UserForService2
'作为数据契约,将最终映射到' 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/
如果您不想使用继承,请执行以下操作:
[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方式来思考它; 如果您在应用程序中定义“用户”,那么它在任何地方都是相同的类型。 某些属性无法从某些其他类或方法中隐藏。
WCF也将把这种类型的信息打包到生成的WSDL中,并且它只会定义一次User类型,因此它需要知道那里有哪些属性。
现在,如果您关心的是实际构造的SOAP消息,并且您不关心WSDL或WSDL将生成的任何客户端将看到什么,那么从技术上讲,您可以让它不将该属性发送到SOAP消息中当它为null时,通过执行:
[DataMember(EmitDefaultValue=false)]
然后,当该属性为null时,它不会包含在序列化中。 如果客户端是从WSDL生成的,那将没有什么区别,因为它的User类型仍然必须包含这两个属性。 它只会改变序列化,而不是像以下那样向客户端发送:
<User>
<PropertyVisibleOnlyForService1 nil="true" />
<PropertyVisibleOnlyForService2>something</PropertyVisibleOnlyForService2>
</User>
它会发送:
<User>
<PropertyVisibleOnlyForService2>something</PropertyVisibleOnlyForService2>
</User>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.