2013-03-02 4 views
2

Мы следующие классы и WCF сервис (с использованием Protobuf-сеть для сериализации):Protobuf-нетто члены не сериализации базового класса

[DataContract] 
[KnownType(typeof(NamedViewModel))] 
public class NamedViewModel<TKey> : IViewModel 
{ 
    [DataMember] 
    public virtual TKey Id { get; set; } 

    [DataMember] 
    public virtual string Name { get; set; } 
} 

[DataContract] 
[KnownType(typeof(ScheduleTemplateViewModel))] 
public class NamedViewModel : NamedViewModel<int> 
{ 
} 

[DataContract] 
public class ScheduleTemplateViewModel : NamedViewModel 
{ 
    [DataMember] 
    public string Comment { get; set; } 
} 

[DataContract] 
public class Container 
{ 
    [DataMember] 
    public IEnumerable<ScheduleTemplateViewModel> Templates { get; set; } 
} 

[ServiceContract] 
public interface IService 
{ 
    [OperationContract] 
    Container Get(); 
} 

public class Service : IService 
{ 
    public IEnumerable<Container> Get() 
    { 
     return new Container { Templates = Enumerable.Range(1, 10) 
      .Select(i => CreateTemplate()).ToArray() }; 
    } 

    private void ScheduleTemplateViewModel CreateTemplate() 
    { 
     var instance = WindsorContainer.Resolve<ScheduleTemplateViewModel>(); 
     // populate instance 
     return instance; 
    } 
} 

У нас есть две проблемы:

  1. мы получаем исключение во время сериализации, что тип Castle DynamicProxy для ScheduleTemplateViewModel является неожиданным. Мы заметили, что в protobuf-net есть собственный код для обработки прокси-серверов NHibernate и EntityFramework ... но не Castle DynamicProxies. Мы работали над этим, добавив дополнительный аргумент case в исходном коде protobuf-net, чтобы проверить тип IProxyTargetAccessor для Castle ... но было бы неплохо, если бы был способ справиться с этим без изменения исходного кода protobuf-net ...

  2. Члены в ScheduleTemplateViewModel (а именно, комментарий) сериализованы правильно ... но базовых классов не являются. У нас уже установлено значение InferTagFromNameDefault равным true в RuntimeTypeModel.Default.

ответ

1
  1. Я могу добавить, что; можете ли вы указать мне полное имя (включая пространство имен) этого интерфейса?

  2. Из примера, который вы даете, none этих значений следует сериализовать, так как ни одна из них не содержит нужной числовой информации о номерах полей. Поскольку вы говорите, что примерно сделать сериализации, я собираюсь предположить, что это упущение в копии/вставке. Protobuf-net попытается использовать информацию Order=n от [DataMember(...)], если ничего лучше не будет. Однако, если необходимо подчеркнуть, что protobuf-net не может использовать [KnownType(...)], а наследование снова нуждается в некоторой явной числовой информации о номере поля. Это наиболее легко добавить с помощью [ProtoInclude(...)], но также может быть предоставлено во время выполнения

+0

Мы InferTagFromNameDefault установлен верно, именно поэтому нам не нужно Order = п информации. Это то, что делает это свойство, верно? Есть ли способ динамического/автоматического добавления ProtoInclude в RuntimeTypeModel во время выполнения? Это клиентское приложение, поэтому я не хочу подвергать себя хиту при запуске, чтобы добавить все в RuntimeTypeModel раньше времени ... То есть есть ли крючок или событие, которое я могу наблюдать как RuntimeTypeModel.Default.TypeAdded + = ... где я могу добавить код для добавления Include? Я не очень люблю помещать атрибуты BCL во все мои типы ... – Jeff

+0

Полное имя интерфейса здесь http://internaltracker.googlecode.com/svn/trunk/Tracker/Castle.Core/DynamicProxy/IProxyTargetAccessor .cs – Jeff

+1

@ JeffN825 моя ошибка за то, что вы не заметили «InferTagFromNameDefault». Иерархию можно управлять с помощью 'RuntimeTypeModel.Default [baseType] .AddSubType (...)' - но это о лучшем, что я могу предложить там –

Смежные вопросы