简体   繁体   English

XmlInclude在单独的程序集中对(继承)序列化继承的类型

[英]XmlInclude to (De)Serialize Inherited Types in Separate Assemblies

I have this scenario: 我有这种情况:

namespace MyApp.Animals
{
  public class Dog : MyApp.Categories.Canine
  ...

So I'm trying to serialize/ deserialize the dog class. 所以我正在尝试对狗类进行序列化/反序列化。 Unfortunately I can't use the [XmlInclude] attribute, because by adding it to the parent class (MyApp.Categories.Canine), I need to add a reference to the assembly in which the parent class exists (MyApp.Animals).. however the child class is already referencing the parent class due to the inheritance... so we have a circular reference. 不幸的是,我无法使用[XmlInclude]属性,因为通过将其添加到父类(MyApp.Categories.Canine)中,我需要添加对父类所在的程序集(MyApp.Animals)的引用。但是由于继承,子类已经在引用父类了……所以我们有一个循环引用。

is there any best practice way of achieving this? 有没有实现这一目标的最佳实践方法? I can work around it by manually serializing/deserializing the properties that exist on the parent class, and just doing the serialization on the child, but that's not very elegant. 我可以通过手动对父类上存在的属性进行序列化/反序列化,然后对子级进行序列化来解决此问题,但这不是很优雅。

Hoping for some better tips.. 希望有一些更好的技巧。

UPDATE: Adding to the example in response to John's comment below... 更新:添加到示例中,以回应以下约翰的评论...

I dont have a full code example (the code i'm working with is massive and complicated), but the issue is that some of the properties that should de/serialise to/from the xml are contained in the parent class, which is in a different assembly to the child class. 我没有完整的代码示例(我正在使用的代码庞大且复杂),但是问题是应该从xml反序列化/从xml序列化的某些属性包含在父类中,该类位于与子类不同的程序集。

Adding the XmlElement attributes to the parent class doesn't work as we are actually doing the de/serialisation on the child class, so it doesnt iterate up to the parent. 将XmlElement属性添加到父类无法正常工作,因为我们实际上是在子类上进行反序列化,因此它不会迭代到父类。 And we can't do it on the parent because we can't add a reference to the child (as the child is already referencing the parent), so the de/serialiser won't know which child to act on. 而且我们无法在父项上执行此操作,因为我们无法添加对子项的引用(因为子项已经在引用父项),因此de / serializer不会知道要对哪个子项进行操作。

To add an extra level of complexity, the object that i have the problem with is actually being de/serialised as part of a greater serialisation, by the following property of a parent object: 为了增加额外的复杂性,实际上,我遇到问题的对象通过父对象的以下属性被反序列化为更大的序列化的一部分:

    [XmlElement("ShippingAddress")]
    public Location ShippingAddress
    {
        get { return _shippingAddress; }
        set { _shippingAddress = value; }
    }

The problem is that the Location type here is the child location type. 问题在于这里的位置类型是子位置类型。 So only the properties in the child type are getting de/serialised... all the properties in the parent type (also called Location, but in a differnet namespace) are not. 因此,只有子类型中的属性被反序列化...父类中的所有属性(也称为Location,但在differentnet命名空间中)都没有。

does that make it any clearer? 这样更清楚了吗?

XmlSerializer has a constructor that takes in an array of types called "extraTypes". XmlSerializer具有一个构造函数 ,该构造函数接受称为“ extraTypes”的类型的数组。 Types in this array will be available during serialization and deserialization just as if you had added XmlInclude attributes. 就像您添加了XmlInclude属性一样,此数组中的类型在序列化和反序列化期间将可用。

var serializer = new XmlSerializer(typeof(Canine), new Type[] { typeof(Dog) });

Update: That approach works if your Xml includes a xsi:type attribute when the type is different from what was declared on the root object. 更新:如果您的Xml在根对象上声明的类型不同时,它的Xml包含xsi:type属性,则该方法有效。 It sounds like you might want to simply always deserialize that property as a different type. 听起来您可能想简单地始终将该属性反序列化为其他类型。 In that case, you can use XmlAttributeOverrides to replace the metadata on the original types. 在这种情况下,可以使用XmlAttributeOverrides替换原始类型上的元数据。 Constructing the XmlSerializer like this: 像这样构造XmlSerializer:

var overrides = new XmlAttributeOverrides();
var xmlAttributes = new XmlAttributes();
xmlAttributes.XmlElements.Add(new XmlElementAttribute("ShippingAddress", typeof(ITSM.Location)));
overrides.Add(typeof(Order), "Location", xmlAttributes);
var ser = new XmlSerializer(typeof(Order), overrides);

will have the same effect as replacing the attributes on the Order.Location property with: 与将Order.Location属性上的属性替换为以下命令具有相同的效果:

[XmlElement("ShippingAddress", typeof(ITSM.Location))]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM