客户端在DataContract上调用new时如何初始化抽象基构造函数?
How to initialize abstract base constructor when client calls new on DataContract?
我正在尝试想出一个变通方法,当使用我的 WCF 服务的客户端对 DataContract 对象执行 new()
时,可以容纳抽象基 class 的构造函数被初始化。我知道 DataContract 对象是作为原始的、未初始化的对象创建的,因此没有调用构造函数。我 运行 跨越了 [OnSerializing]
、[OnSerialized]
、[OnDeserializing]
和 [OnDeserialized]
属性的用户,我发现序列化不支持它们WCF 的引擎,除非您明确强制它使用 XML,这在这种特定情况下是不需要的。这是我正在尝试使用的非常简化的编码示例。
[DataContract(Namespace = "http://somenamespace/Data/ContractBase/v1")]
public abstract ContractBase
{
[DataMember(IsRequired = true)]
public SomeDataContract BaseClassObject { get; set; }
public string Name { get; set; }
public ContractBase()
{
BaseClassObject = new SomeDataContract("randomConstructorArgument");
Name = "Ezra";
}
}
[DataContract(Namespace = "http://somenamespace/Data/TheClass/v1")]
[KnownType(typeof(ContractBase))]
public sealed class TheClass : ContractBase
{
[DataMember]
public PetDataContract MyPet { get; set; }
[DataMember]
public int SomeIntProperty { get; set; }
public TheClass()
: base()
{
MyPet = new PetDataContract ("Fido");
SomeIntProperty = -1;
}
}
我知道执行 TheClass myClass = new TheClass();
的客户端不会初始化基本构造函数,因为从未调用 TheClass
的构造函数。我尝试添加以下方法以在序列化发生但没有成功时触发。
private void Initialize()
{
MyPet = new PetDataContract ("Fido");
SomeIntProperty = -1;
base.Initialize();
}
[OnSerializing]
private void OnSerializing(StreamingContext c)
{
Initialize();
}
基础 class 也将具有 Initialize 方法,因此 "constructors" 将被链接。构造函数本身将更新为包括 Initialize();
调用以使用相同的公共代码源。
有没有办法在不强制通过 XmlSerializer
完成序列化的情况下处理这个问题?我当前的解决方法是在 WCF 服务中提供一种方法来在服务器上创建对象,return post-构造函数版本。
public TheClass CreateTheClass(TheClass contract)
{
// Calls the constructor of TheClass and its base constructor.
return new TheClass();
}
这确实按预期工作,但由于网络 I/O 成本,我宁愿避免这是一个额外的服务调用。任何帮助将不胜感激。
谢谢!
根据 this article,您提到的属性应该可以很好地与 DataContractSerializer
配合使用。你的最后一个例子有点奇怪 - 你试图使用 OnSerializing
属性,同时说在 WCF 反序列化期间不调用构造函数。
我建议将您的方法与 OnDeserializing
标记的 Initialize
方法一起使用(或者 OnDeserialized
如果您想在反序列化完成后调用您的代码)属性。
我正在尝试想出一个变通方法,当使用我的 WCF 服务的客户端对 DataContract 对象执行 new()
时,可以容纳抽象基 class 的构造函数被初始化。我知道 DataContract 对象是作为原始的、未初始化的对象创建的,因此没有调用构造函数。我 运行 跨越了 [OnSerializing]
、[OnSerialized]
、[OnDeserializing]
和 [OnDeserialized]
属性的用户,我发现序列化不支持它们WCF 的引擎,除非您明确强制它使用 XML,这在这种特定情况下是不需要的。这是我正在尝试使用的非常简化的编码示例。
[DataContract(Namespace = "http://somenamespace/Data/ContractBase/v1")]
public abstract ContractBase
{
[DataMember(IsRequired = true)]
public SomeDataContract BaseClassObject { get; set; }
public string Name { get; set; }
public ContractBase()
{
BaseClassObject = new SomeDataContract("randomConstructorArgument");
Name = "Ezra";
}
}
[DataContract(Namespace = "http://somenamespace/Data/TheClass/v1")]
[KnownType(typeof(ContractBase))]
public sealed class TheClass : ContractBase
{
[DataMember]
public PetDataContract MyPet { get; set; }
[DataMember]
public int SomeIntProperty { get; set; }
public TheClass()
: base()
{
MyPet = new PetDataContract ("Fido");
SomeIntProperty = -1;
}
}
我知道执行 TheClass myClass = new TheClass();
的客户端不会初始化基本构造函数,因为从未调用 TheClass
的构造函数。我尝试添加以下方法以在序列化发生但没有成功时触发。
private void Initialize()
{
MyPet = new PetDataContract ("Fido");
SomeIntProperty = -1;
base.Initialize();
}
[OnSerializing]
private void OnSerializing(StreamingContext c)
{
Initialize();
}
基础 class 也将具有 Initialize 方法,因此 "constructors" 将被链接。构造函数本身将更新为包括 Initialize();
调用以使用相同的公共代码源。
有没有办法在不强制通过 XmlSerializer
完成序列化的情况下处理这个问题?我当前的解决方法是在 WCF 服务中提供一种方法来在服务器上创建对象,return post-构造函数版本。
public TheClass CreateTheClass(TheClass contract)
{
// Calls the constructor of TheClass and its base constructor.
return new TheClass();
}
这确实按预期工作,但由于网络 I/O 成本,我宁愿避免这是一个额外的服务调用。任何帮助将不胜感激。
谢谢!
根据 this article,您提到的属性应该可以很好地与 DataContractSerializer
配合使用。你的最后一个例子有点奇怪 - 你试图使用 OnSerializing
属性,同时说在 WCF 反序列化期间不调用构造函数。
我建议将您的方法与 OnDeserializing
标记的 Initialize
方法一起使用(或者 OnDeserialized
如果您想在反序列化完成后调用您的代码)属性。