WCF - 使用完全相同的数据契约的多个服务契约
我有一个新问题要问 WCF 专家。
因此,我有一个类 User
,它接近我用于数据库操作的数据库中的“用户”表示形式。现在,我想要有 2 个不同的服务合约,它们使用此类作为数据合约,但每个服务合约都以自己的方式...我的意思是,
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'
进行数据库操作,我可以选择什么来实现此目的?我真的需要创建不同的数据合约还是有其他更聪明的方法?
最好不仅给我解决方案,还向我解释一些最佳实践和替代方案。
先感谢您。
编辑1: 我在这里添加了一个虚拟 DBLayer 类,以便更好地概述以及为什么我认为在这种情况下继承可能不好。
解决方案是使用另一个“UserForService1
”和“UserForService2
”作为数据协定,这些协定将在末尾映射到“User
” ’但我想要一些其他的观点。
编辑2:非常好的文章,在这种情况下对我有帮助:http://bloggingabout.net/blogs/vagif/archive/2009/03/29/iextensibledataobject-is-not-only-for-backward-compatibility.aspx
I have a new question for WCF gurus.
So, I have a class User
which is close to the 'User' representation from the DB which I use for database operations. Now, I would like to have 2 different service contracts that use this class as data contract, but each in their own way... I mean,
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
}
So, the idea is that each service will get a different kind of user, subset of 'User'
. Keeping in mind that I want to use the 'User'
as is for DB operations, what would be my options to achieve this? Do I really need to create different data contracts or is there another smarter way?
Best would be to not only give me the solution, but also to explain me some best practices and alternatives.
Thank you in advance.
EDIT1:
I added a dummy DBLayer class here for a better overview and why I think the inheritance may not be good in this case.
A solution would be of having another 'UserForService1
' and 'UserForService2
' as data contracts which would map at the end from/into an 'User
' but I wanted some other points of view.
EDIT2: Very good article which helped me in this case: http://bloggingabout.net/blogs/vagif/archive/2009/03/29/iextensibledataobject-is-not-only-for-backward-compatibility.aspx
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以为每个服务创建单独的 DTO,但您的情况实际上非常适合 装饰器模式
:对于 Service2 类似的代码,只公开您关心的内容......
You could create separate DTO's for each service but your case would actually be ideal for a Decorator pattern:
and for Service2 similar code, that exposes only what you care for there...
如果它们被设计为代表不同类型的用户,那么它们应该是不同的类。我同意评论中的 phoog,您应该从共享 User 类中派生出您想要的类型,并将特定的服务属性添加到派生类中。
在这种情况下,你为什么不认为继承是件好事呢?如果您向我们提供更多详细信息,我们可以尝试修改建议以适合您的实际问题。
If they are designed to represent different types of users, they should be different classes. I agree with phoog in the comments, you should derive the type you want from the shared User class and add the specific service properties to the derived classes.
Why don't you think inheritance would be good in this case? If you give us some more details, we could try to revise the suggestions to suit your actual problem.
正如评论中所建议的,您可以有两个从基本用户派生的类,然后使用 Data合约已知类型,您就可以完成您想要的目标。有关更多示例,请参阅以下链接。
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
As suggested in the comment, you can have two classes deriving from a base User then using Data Contract Known Types, you can accomplish your desired goal. See the following links for more examples.
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
如果您不想使用继承,例如:
那么我不确定您会做什么。此时您有点违反了类型声明的原则。以普通的 .NET 方式思考它;如果您在应用程序中定义“User”,那么它在任何地方都是相同的类型。某些属性无法对某些其他类或方法隐藏。
WCF 还将将此类型信息打包到生成的 WSDL 中,并且它只会定义一次 User 类型,因此它需要知道其中有哪些属性。
现在,如果您只关心构建的实际 SOAP 消息,并且不关心 WSDL 或从 WSDL 生成的任何客户端将看到的内容,那么从技术上讲,您可以让它不将该属性发送到 SOAP 消息中当它为空时,通过执行以下操作:
然后,当该属性为空时,它不会包含在序列化中。如果客户端是从 WSDL 生成的,那么这不会产生任何真正的区别,因为它的 User 类型仍然必须包含这两个属性。它只会更改序列化,以便不向客户端发送类似以下内容:
而是发送:
If you don't want to use inheritance, something like:
Then I'm not sure what you would do. Your sortof breaking the principals of an type declaration at that point. Think of it in a normal .NET way; if you define "User" in your application, then it is the same type everywhere. Some properties cant be hidden from certain other classes or methods.
WCF is also going to pack this type information into the generated WSDL, and it is only going to define the User type once, so it needs to know what properties are there.
Now, if all you care about is the actual SOAP message that is constructed, and you don't care about the WSDL or what any clients generated off the WSDL will see, then technically you can have it not emit that property into the SOAP message when it is null, by doing:
Then when that property is null, it wont be included in the serialization. That would make no real difference if the client was generated from the WSDL though, as its User type would still have to contain both properties. It would just change the serialization so that instead of sending the client something like:
it would instead send: