Sterling Db не использует пользовательскую сериализацию - PullRequest
2 голосов
/ 03 августа 2011

Я использую Sterling DB в приложении WP7 и пытаюсь реализовать специальный сериализатор для, надеюсь, повышения производительности.

Я приведу пример (извините за все форматирование, пытаясь сжать его, чтобы он был маленьким). Учитывая тип, который наследует List<string>:

public class TypedList : List<string>
{
    public Guid ObjectId { get; set; }

    public TypedList() {  }
    public TypedList(int count) : base(count) { }
}

И это сериализатор:

public class TypedListSerializer : Wintellect.Sterling.Serialization.BaseSerializer
{
    public override bool CanSerialize(Type targetType)
    {
        return targetType.Equals(typeof(TypedList));   
    }

    public override object Deserialize(Type type, BinaryReader reader)
    {
        int count = reader.ReadInt32();
        var list = new TypedList(count);

        for (int i = 0; i < count; i++)
            list.Add(reader.ReadString());

        return list;
    }

    public override void Serialize(object target, BinaryWriter writer)
    {
        var list = (TypedList)target;
        writer.Write(list.Count);

        foreach (string s in list)
            writer.Write(s);
    }
}

Я регистрирую сериализатор с двигателем:

_engine = new SterlingEngine();
_engine.SterlingDatabase.RegisterSerializer<TypedListSerializer>();
_engine.Activate();

Предполагается таблица TypedList типов. Теперь, когда я пытаюсь сохранить / загрузить этот тип на экземпляре Sterling:

// _instance is a class that inherits BaseDatabaseInstance from the Sterling code.
_instance.Save<TypedList>(list);
_instance.Flush();
_instance.Load<TypedList>(g); // g is Guid.

Он вызывает в CanSerialize, но Type, который ему дан, это T из List<T>, класса, от которого я наследую. Если вы измените string на int, он скажет мне, что тип int.

Кто-нибудь еще имел эту проблему? Это проблема Стерлинга или информация о типах дженериков?

Обновление : В соответствии с предложением Марка о наследовании я изменил свой тип следующим образом:

public class TypedList
{
    public Guid ObjectId { get; set; }
    public List<int> Items { get; set; }

    public TypedList() 
    {
        Items = new List<int>();
    }
}

Похоже, что сериализатор выполняет проверку из TypedList вместо самого типа. Я предполагаю, что теперь это ошибка с тем, как я использую стерлинг. Моя строка регистрации таблицы выглядит так:

protected override List<ITableDefinition> RegisterTables()
{
    return new List<ITableDefinition>
    {
        CreateTableDefinition<TypedList, Guid>(l => l.ObjectId)
    };
}

Ответы [ 2 ]

3 голосов
/ 10 августа 2011

Как раз того, чего стоит - Sterling ожидает полного контроля над сущностями «верхнего уровня», чтобы он мог строить ключи, индексы и другие части, которые ему нужны для функционирования. Вот почему он никогда не вызывает настраиваемый сериализатор для объекта верхнего уровня (тот, который вы определяете, чтобы иметь индексы и ключи). Пользовательские сериализаторы предназначены для свойств этих таблиц. Вышеприведенное исправление является правильным, поскольку теперь он видит список как свойство, а не «элемент» верхнего уровня, который пытается сериализовать.

1 голос
/ 03 августа 2011

Я не знаком с этим сериализатором, но нередко сериализаторы «берут на себя», когда он поступает из списков - используя встроенный механизм для представления [n] элементов, но используя обычный конвейер для каждого элемента вочередь.Я подозреваю (чисто догадочно), что именно это и происходит здесь.

Обратите внимание, что как следствие (и общего с рядом других сериализаторов) может быть нежелательно иметьзначения в самом списке (то есть ObjectId).Я бы обычно использовал инкапсуляцию, а не наследование:

public class TypedList
{
    public Guid ObjectId { get; set; }

    private readonly List<string> items = new List<string>();
    public List<string> Items { get { return items; } }
}

т.е. что-то, что имеет ObjectId, а имеет список, а не что-то, что имеет ObjectId и - это список.

...