基于XML Serializer的快速和脏的反射

时间:2009-12-01 02:18:37

标签: c# .net serialization xml-serialization

有没有人知道基于反射的XML序列化器的快速而又脏的实现?

由于可怕的启动时间,我希望删除我的XML序列化代码。 我知道sgen.exe ,但不想让我的构建和打包过程复杂化。

我们在启动时使用XML序列化从文件中提取配置值,反射命中率最小,我们最多说20-40个值。我们这里不需要任何超快的东西。在我的案例中,我只是不想接受编译似乎 500-700ms 的XML序列化程序。

我也想控制代码,因为我希望非常强大的错误处理。

我知道protobuf.net,但它可能有点矫枉过正。看看数据合同,他们可能有点受限,需要我想避免的大量装饰。

4 个答案:

答案 0 :(得分:3)

如果只有20到40个值,为什么不扔掉所有的序列化malarkey和手动代码呢?您应该能够立即编写设置阅读课程。哎呀,你可以编码生成它并提前回家。这样,它可以像你喜欢的那样强大和错误处理,并且它的卸载速度将超过700毫秒。

答案 1 :(得分:1)

您是否尝试过使用sgen预编译序列化程序?

http://blog.lab49.com/archives/2358

答案 2 :(得分:1)

如果您将sgen.exe与/ k [eep]选项一起使用,它将保留生成的C#源,然后您可以将其集成到项目中。您可以根据需要自定义它。

编辑:换句话说,你使用sgen不是作为预编译器(你说你做不到),而是作为代码生成器使用。

答案 3 :(得分:1)

I wrote my own ...如果有人在BSD许可下有类似的规范,请随意使用它。

以下是一些示例测试,它生成可爱的XML,就像XML序列化器一样,对于不能选择sgen的配置文件场景,速度要快得多:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using NUnit.Framework;
using MediaBrowser.Library.Persistance;

namespace TestMediaBrowser.Unit {
    [TestFixture]
    public class TestXmlSettings {

        enum Farts { 
            Smelly, 
            SilentButDeadly
        }

        class Monster {
            public Weapon Weapon; 
        }

        class Weapon {
            public int LaserCount { get; set; }
        }

        class Farter {
            public Farts Smell = Farts.Smelly;
        }

        class Group {
            public List<Person> People;
        }

        class Person {
            public int Age = 1; 
            public string Name = "Default";
            public bool Happy = true;
            public DateTime Birthdate = DateTime.Now;  
        }

        class Account {
            public Person Person;
            public int Balance;
        }

        const string CONFIG_FILE = "test.config";

        private void ClearConfig() {
            if (File.Exists(CONFIG_FILE)) {
                File.Delete(CONFIG_FILE);
            }
        }

        public void TestProperty() {
            ClearConfig();
            Monster monster = new Monster();
            XmlSettings<Monster> settings = XmlSettings<Monster>.Bind(monster, CONFIG_FILE);
            monster.Weapon = new Weapon();
            monster.Weapon.LaserCount = 99;
            settings.Write();

            monster = new Monster();
            settings = XmlSettings<Monster>.Bind(monster, CONFIG_FILE);

            Assert.AreEqual(monster.Weapon.LaserCount, 99);
        } 

        public void TestEnum() {
            ClearConfig();
            Farter farter = new Farter();
            XmlSettings<Farter> settings = XmlSettings<Farter>.Bind(farter, CONFIG_FILE);
            farter.Smell = Farts.SilentButDeadly;
            settings.Write();

            farter = new Farter();
            settings = XmlSettings<Farter>.Bind(farter, CONFIG_FILE);

            Assert.AreEqual(farter.Smell, Farts.SilentButDeadly);
        } 

        [Test]
        public void TestList() {
            ClearConfig();
            Group group = new Group();
            group.People = new List<Person>();
            group.People.Add(new Person());
            group.People.Add(new Person());
            XmlSettings<Group> settings = XmlSettings<Group>.Bind(group, CONFIG_FILE);
            settings.Write();

            group = new Group();
            settings = XmlSettings<Group>.Bind(group, CONFIG_FILE);

            Assert.AreEqual(group.People.Count, 2);

        }

        [Test]
        public void BasicValueTypeTest() {
            ClearConfig();
            var person = new Person();
            XmlSettings<Person> settings = XmlSettings<Person>.Bind(person, CONFIG_FILE);
            person.Age = 3;
            person.Name = "Sam";
            person.Happy = false;
            person.Birthdate = DateTime.Today;
            settings.Write();

            person = new Person();
            settings = XmlSettings<Person>.Bind(person, CONFIG_FILE);

            Assert.AreEqual(person.Age, 3);
            Assert.AreEqual(person.Name, "Sam");
            Assert.AreEqual(person.Happy, false);
            Assert.AreEqual(person.Birthdate, DateTime.Today);
        }

        [Test]
        public void NestedObjectTypeTest() {
            ClearConfig();
            var account = new Account();
            var settings = XmlSettings<Account>.Bind(account, CONFIG_FILE);
            var person = new Person();
            person.Age = 3;
            person.Name = "Sam";
            person.Happy = false;
            person.Birthdate = DateTime.Today;

            account.Person = person;
            account.Balance = 999;

            settings.Write();

            account = new Account();
            settings = XmlSettings<Account>.Bind(account, CONFIG_FILE);


            person = account.Person;
            Assert.AreEqual(account.Balance, 999);
            Assert.AreEqual(person.Age, 3);
            Assert.AreEqual(person.Name, "Sam"); 
            Assert.AreEqual(person.Happy, false); 
            Assert.AreEqual(person.Birthdate, DateTime.Today); 
        }
    }
}