次のクラスとWCFサービスがあります(シリアル化にprotobuf-netを使用)。
[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;
}
}
2つの問題があります。
シリアル化中に、ScheduleTemplateViewModelのCastleDynamicProxyタイプが予期しないという例外が発生します。protobuf-netには、NHibernateプロキシとEntityFrameworkプロキシを処理するカスタムコードがありますが、CastleDynamicProxiesはありません。これを回避するには、protobuf-netソースコードにcaseステートメントを追加して、CastleのIProxyTargetAccessorタイプをチェックします...しかし、protobuf-netソースコードを変更せずにこれを処理する方法があれば便利です...
ScheduleTemplateViewModelのメンバー(つまりComment)は正しくシリアル化されますが、基本クラスのメンバーは正しくシリアル化されません。RuntimeTypeModel.DefaultではすでにInferTagFromNameDefaultがtrueに設定されています。