有没有人知道基于反射的XML序列化器的快速而又脏的实现?
由于可怕的启动时间,我希望删除我的XML序列化代码。 我知道sgen.exe ,但不想让我的构建和打包过程复杂化。
我们在启动时使用XML序列化从文件中提取配置值,反射命中率最小,我们最多说20-40个值。我们这里不需要任何超快的东西。在我的案例中,我只是不想接受编译似乎 500-700ms 的XML序列化程序。
我也想控制代码,因为我希望非常强大的错误处理。
我知道protobuf.net,但它可能有点矫枉过正。看看数据合同,他们可能有点受限,需要我想避免的大量装饰。
答案 0 :(得分:3)
如果只有20到40个值,为什么不扔掉所有的序列化malarkey和手动代码呢?您应该能够立即编写设置阅读课程。哎呀,你可以编码生成它并提前回家。这样,它可以像你喜欢的那样强大和错误处理,并且它的卸载速度将超过700毫秒。
答案 1 :(得分:1)
您是否尝试过使用sgen预编译序列化程序?
答案 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);
}
}
}