c# - C# 使用 proto-buf 序列化继承的类而不使用 ProtoInclude
问题描述
我有一个项目,用户可以为它开发插件。在他们的插件中,他们必须扩展一个抽象基类。在我的项目的核心中,动态加载插件(dll)并新建这些类。
代码核心中的基类:
[ProtoContract]
public abstract class BaseOutput
{
public string OutputName {get;}
[ProtoMember(1)]
public int X { get; set; }
}
插件示例(在其他项目中):
[ProtoContract]
public class MyOutput : BaseOutput
{
public override OutputName { get { return "MyOutput";} }
[ProtoMember(11)]
public double A { get; set; }
[ProtoMember(12)]
public double B { get; set; }
[ProtoMember(13)]
public double C { get; set; }
}
我知道在 BaseOutput 上我必须添加 [ProtoInclude(10, typeof(MyOutput ))] 但是当我开发我的应用程序的核心时不知道用户将添加到程序中的插件。但我希望可以序列化所有类,使用 protobuf 扩展 BaseOutput。
解决办法是什么?
解决方案
可以通过RuntimeTypeModel
API 在运行时使用 protobuf-net 配置这种类型的关系,如下所示。但是:每次您的应用程序运行时,使用的密钥(在示例中)都是可靠且确定的,这一点至关重要。含义:无论是否有人添加/删除其他插件,您每次都需要某种可靠的方法来获取您的特定插件类型(这意味着:仅按字母顺序排列它们可能还不够)。另外:在加载的不同插件中必须是唯一的。42
42
42
using ProtoBuf;
using ProtoBuf.Meta;
[ProtoContract]
public abstract class BaseOutput
{
public abstract string OutputName { get; }
[ProtoMember(1)]
public int X { get; set; }
}
[ProtoContract]
public class MyOutput : BaseOutput
{
public override string OutputName { get { return "MyOutput"; } }
[ProtoMember(11)]
public double A { get; set; }
[ProtoMember(12)]
public double B { get; set; }
[ProtoMember(13)]
public double C { get; set; }
public override string ToString()
=> $"A={A}, B={B}, C={C}"; // to show working
}
class Program
{
static void Main()
{
var pluginType = typeof(MyOutput); // after loading the plugin etc
var baseType = RuntimeTypeModel.Default[typeof(BaseOutput)];
baseType.AddSubType(42, pluginType);
BaseOutput obj = new MyOutput { A = 1, B = 2, C = 3 };
var clone = Serializer.DeepClone(obj);
// outputs: A=1, B=2, C=3 - so: working (yay!)
System.Console.WriteLine(clone.ToString());
}
}
推荐阅读
- c# - Visual Studio 2019 .NET Core 3.1 WinForm 视图超时 (Studio 16.7.3)
- dependency-injection - 在 asp.net core 3.1 中使用 Autofac 的 ServiceLocator
- ruby-on-rails - 如何正确评估页面是否包含某些带有水豚的内容?
- javascript - 移位时如何选择选择键
- cplex - 如何在 CPLEX 中检查 MILP 是否有可行的解决方案
- html - 从父组件到子组件html中的元素的Angular 10 scrollTo
- python - Keras RNN 准确率没有提高
- compilation - Solidity 错误:无法构造包含(嵌套)映射的结构
- firebase - Firebase ML Kit 中文翻译 - 离线模式
- python - 数组之间的最大差异