WCF如何为外部类生成DataContract

本文关键字:DataContract 外部 WCF | 更新日期: 2023-09-27 18:29:09

我想在我的wcf服务中使用其他解决方案中已经存在的类。所以我必须添加DataContract。

实现这一目标的最佳方式是什么?我听说DataContract代理是一种方法,但我真的不知道该如何使用它。

现有类别

public class Person
{
    public string Name{get; set;}
    public long Size{get; set;}
    public DateTime Birthdate{get; set;}
    public Person(string name, long size, DateTime birthdate)
    {
        this.Name = name;
        this.Size = size;
        this.Birthdate = birthdate;
    }
}

这就是外部类的样子。有人能给我举个例子,告诉我如何把它放在我的wcf服务中吗。

编辑

我有一个windows服务,其中有一个类Person。我在windows服务中的方法返回Persons的列表,因此为List<Person>。现在我正试图将此列表传递给我的wcf服务。因此,我需要将DataContract添加到该类中。我必须在wcf服务中编写一个新类吗?或者我可以从windows服务中移交我的类吗。

WCF如何为外部类生成DataContract

我刚刚投票支持Tom Redfern解决方案,但为了使答案完整,我会添加更多链接,让作者决定是否真的想使用代理。在非常类似的问题上,与汤姆斯的建议非常相似的问题被投票通过。你可以浏览评论和答案中的链接。

你可以自己检查代孕者是什么以及如何使用它们。从技术上讲是的,您可以使用它来模拟和代理来自第三方程序集的现有类(这里是非常详细的示例)。

为什么问题作者会出现这种情况?我认为只有当真正的案例不是问题中的Person类,而是更复杂的东西时。

代理已经存在了一段时间,甚至在WCF之前,他们的想法很简单:用另一种类型B("代理")替换作为要序列化的对象图一部分的一种类型a。我们想要这样做的主要原因要么是因为类型A根本不可序列化,要么是因为它没有我们想要的序列化格式,所以我们使用代理来更改它。第一种情况很简单——有时你有一个来自第三方的类型或无法修改以适应序列化的遗留库,但它是您希望在客户端和服务器之间交换的对象图的一部分。一种可能的解决方案是在数据传输对象(DTO)中复制图,该对象只包含需要序列化的数据。然而,有时这可能不是最好的方法(类型太多,在DTO和具有业务逻辑的对象之间转换成本很高,等等),因此代理可能是一种出路。第二种情况(希望更改序列化格式)并不常见,但在某些情况下,用户希望更改类型的序列化方式。

首先,Person类型是在程序集中定义的吗?或者它被捆绑到一个exe中?如果是后者,那么尽管您可以向exe添加二进制引用,但这被认为是不好的做法。

如果它是在程序集中定义的,则可以将Person类型用作WCF服务中的数据协定类型。您只需创建对程序集的二进制引用,DataContractSerializer就会跨服务边界序列化此类型。

正如微软在这里所说:

默认情况下,DataContractSerializer推断数据约定序列化所有公开可见的类型。所有公共读/写该类型的属性和字段被序列化

然而,是否应该这样做是另一个问题。

在WCF项目中定义一个Person类型,公开该类型(或根据您的评论,该类型的List<>),然后让客户端在调用服务时将其Person类型映射到服务上定义的Person类型会容易得多。

如果类型被封装在exe中,这实际上是唯一可以选择的选项。即使它在dll中,您仍然应该这样做,因为它将服务与使用者解耦。依赖关系的方向应该是消费者->服务,而不是服务->消费者。

如果您想避免编写映射代码,可以使用许多对象映射器。

[DataContract]
public class Person
{
    [DataMember] public string Name { get; set; }
    [DataMember] public long Size { get; set; }
    [DataMember] public DateTime Birthdate { get; set; }
    public Person(string name, long size, DateTime birthdate)
    {
        this.Name = name;
        this.Size = size;
        this.Birthdate = birthdate;
    }
}