你如何找出时候,你已经通过XML序列化装? [英] How do you find out when you've been loaded via XML Serialization?

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

问题描述

我想通过XML序列化加载对象树,并在瞬间将加载的对象,并创建树很愉快。围绕事实上我的问题,围绕这些类支持审计水平。我希望能够做的就是调用每个对象的一些方法后,它已经完成了正装。

有关参数的缘故,假设我有不同类不同层次,是一个相当普通的对象树:

 <客户名称=富律师公司>
   <办公以及ISHq =真>
     <街> 123条街道< /街>
     <城市名称=Anytown>
       <国名=Anystate>
         <国家名称=我的祖国/>
       < /国家>
     < /城镇>
   < /办公及GT;
   <办公以及ISHq =FALSE>
     <街> 456高街< /街>
     <城市名称=Anycity>
       <国名=Anystate>
         <国家名称=我的祖国/>
       < /国家>
     < /城镇>
   < /办公及GT;
 < /客户>
 

有没有使用默认的序列化器(在这你可以这样建立 ShouldSerializeFoo 方法类似的方式),以确定何时加载完成后对每个对象什么办法?

编辑: 我要指出,露出一个类似于 OnLoaded()的方法,我的的明显的情况下,可以的deserialising呼叫后,令我成为一个不好的事情。

EDIT2: 为了便于讨论,这是我目前的<击>破解办法,其工作的基本水平,但孩子城市节点仍然认为它需要储存的变化(在现实世界中的对象模型是一个复杂得多,但是这将至少编译,而不需要完整的源)

 公共类办公
{
    [XmlAttribute(以及ISHq)]
    公共BOOL IsHeadquarters {获得;组; }

    [的XmlElement]
    公共字符串街{获得;组; }

    [的XmlElement]
    公溪镇镇{获得;组; }

    受保护的虚拟无效OnLoaded(){}

    公共静态OfficeCollection搜索()
    {
        OfficeCollection RETVAL =新OfficeCollection();
        字符串的xmlString = @
                    &LT;办公以及ISHq ='真'&GT;
                        &LT;街&GT; 123条街道&LT; /街&GT;
                        &LT;城市名称='Anytown'&GT;
                            &LT;国家名称='Anystate'&GT;
                                &LT;国家名称='我的国家/&GT;
                            &LT; /国家&GT;
                        &LT; /城镇&GT;
                    &LT; /办公及GT;;

        XmlSerializer的XS =新的XmlSerializer(retval.GetType());
        XmlReader的XR =新的XmlTextReader(的xmlString);
        RETVAL =(OfficeCollection)xs.Deserialize(XR);

        的foreach(办公室thisOffice在RETVAL)
        {
            thisOffice.OnLoaded();
        }
        返回RETVAL;
    }
}
 

解决方案

嗯......这还不是pretty的,但你可以重构你的逻辑反序列化到一个专用的类,它可以通知它源于XML的反序列化对象前将它返回给调用者。

更新:我想这应该是很容易做到不偏离由框架奠定了图案太远...你只需要确保你使用的CustomXmlSerializer。需要此通知类只需要实现IXmlDeserializationCallback

 使用的System.Xml.Serialization;

命名空间Custom.Xml.Serialization
{
    公共接口IXmlDeserializationCallback
    {
        无效OnXmlDeserialization(对象发件人);
    }

    公共类CustomXmlSerializer:XmlSerializer的
    {
        保护覆盖对象反序列化(XmlSerializationReader阅读器)
        {
            VAR的结果= base.Deserialize(读卡器);

            VAR deserializedCallback =结果为IXmlDeserializationCallback;
            如果(deserializedCallback!= NULL)
            {
                deserializedCallback.OnXmlDeserialization(本);
            }

            返回结果;
        }
    }
}
 

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>

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?

Edit: 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".

Edit2: 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;
    }
}

解决方案

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.

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天全站免登陆