你怎么知道你什么时候已经通过 XML 序列化加载了? [英] How do you find out when you've been loaded via XML Serialization?

查看:15
本文介绍了你怎么知道你什么时候已经通过 XML 序列化加载了?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过 XML 序列化加载对象树,目前它将加载对象,并非常愉快地创建树.我的问题与这些类支持一定级别的审计有关.我希望能够做的是在每个对象加载完成后调用一些方法.

I'm trying to load a tree of objects via XML serialisation, and at the moment it will load the objects in, and create the tree quite happily. My issue revolves around the fact that these classes support a level of auditing. What I'd like to be able to do is call some method on each object after it has finished being loaded.

为了便于论证,假设我有一个相当通用的对象树,在不同级别具有不同的类,例如:

For the sake of argument, assume I have a fairly generic object tree with differing classes at different levels, like:

 <Customer name="Foo Bar Inc.">
   <Office IsHq="True">
     <Street>123 Any Street</Street>
     <Town name="Anytown">
       <State name="Anystate">
         <Country name="My Country" />
       </State>
     </Town>
   </Office>
   <Office IsHq="False">
     <Street>456 High Street</Street>
     <Town name="Anycity">
       <State name="Anystate">
         <Country name="My Country" />
       </State>
     </Town>
   </Office>
 </Customer>

有什么方法可以使用默认的序列化程序(类似于您可以创建像 ShouldSerializeFoo 这样的方法)来确定每个对象的加载何时完成?

Is there any way using the default serialisers (In the similar way that you can create methods like ShouldSerializeFoo) to determine when loading has finished for each object?

我应该指出,在反序列化后暴露类似于 OnLoaded() 方法的明显情况,我可以调用,这让我觉得是一件坏事".

I should point out that the obvious case of exposing something akin to an OnLoaded() method that I could call after deserialising, strikes me as being a "bad thing to do".

编辑 2:为了讨论起见,这是我目前的 hack 方法",它适用于基本级别,但子 City 节点仍然认为它需要通过更改来保存(在现实世界中,对象模型复杂得多,但这至少可以编译,不需要完整的源代码)

For the sake of discussion this is my current hack "approach", which works for the basic level, but the child City node still thinks it needs to be saved with changes (in the real world the object model is a lot more complex, but this will at least compile, without the need for full source)

public class Office
{
    [XmlAttribute("IsHq")]
    public bool IsHeadquarters { get; set; }

    [XmlElement]
    public string Street { get; set; }

    [XmlElement]
    public Town Town { get; set; }

    protected virtual void OnLoaded() {}

    public static OfficeCollection Search()
    {
        OfficeCollection retval = new OfficeCollection();
        string xmlString = @"
                    <Office IsHq='True'>
                        <Street>123 Any Street</Street>
                        <Town name='Anytown'>
                            <State name='Anystate'>
                                <Country name='My Country' />
                            </State>
                        </Town>
                    </Office>";

        XmlSerializer xs = new XmlSerializer(retval.GetType());
        XmlReader xr = new XmlTextReader(xmlString);
        retval = (OfficeCollection)xs.Deserialize(xr);

        foreach (Office thisOffice in retval)
        {
            thisOffice.OnLoaded();
        }
        return retval;
    }
}

推荐答案

嗯...它仍然不漂亮,但您可以将您的反序列化逻辑重构为一个专用类,该类可以在返回之前通知反序列化对象它源自 XML给来电者.

Hmmm... it's still not pretty but you could refactor your deserialization logic into a dedicated class which could notify the deserialized object that it originated from XML before returning it to the caller.

更新:我认为这应该很容易做到,而且不会偏离框架所规定的模式……您只需要确保使用 CustomXmlSerializer.需要这个通知的类只需要实现 IXmlDeserializationCallback

Update: I think this should be fairly easy to do without straying too far from the patterns laid by the framework... you'd just need to ensure that you use the CustomXmlSerializer. Classes that need this notification just need to implement IXmlDeserializationCallback

using System.Xml.Serialization;

namespace Custom.Xml.Serialization
{
    public interface IXmlDeserializationCallback
    {
        void OnXmlDeserialization(object sender);
    }

    public class CustomXmlSerializer : XmlSerializer
    {
        protected override object Deserialize(XmlSerializationReader reader)
        {
            var result = base.Deserialize(reader);

            var deserializedCallback = result as IXmlDeserializationCallback;
            if (deserializedCallback != null)
            {
                deserializedCallback.OnXmlDeserialization(this);
            }

            return result;
        }
    }
}

这篇关于你怎么知道你什么时候已经通过 XML 序列化加载了?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆