我有一个插件系统,插件本身可以有多个运行时实例。这些实例是通过各种API为插件本身提供的配置对象定义的。
配置包含父应用程序理解的特定部分,但插件需要通过子类化来指定自己的部分。
[Serializable]
public class PluginConfiguration {
public string Name { get; set; }
}
public class MyPluginConfiguration : PluginConfiguration {
public string AccessToken { get; set; }
}
这部分是技术原因,因为它允许主应用程序将整个对象序列化为JSON / XML /等。进入数据库以保持常见配置和插件特定配置。
每个插件都托管在自己的AppDomain中。但是,当我尝试从主应用程序域和插件中读取插件配置时,我遇到了麻烦(MarshalByRefObject
返回其MyPluginConfiguration
对象实例。
有没有办法在基类中执行一些序列化魔术,以确保将对象实例序列化为PluginConfiguration
个实例?序列化MyPluginConfiguration
实例的问题是:
[Serializable]
[Serializable]
,他们仍然没有在主应用程序域中加载他们的程序集。理想情况下,我希望将实现限制为PluginConfiguration
基类。旧的[Serializable]
语义和AppDomains不是.Net中最常见的概念,如果他们不需要处理它们,我想隐藏其中一些方面的内容。
答案 0 :(得分:0)
根据[Serializable]
注意:XML有IXmlSerializable 和Javascript也不同。我相信JSON.net将ISerializable对象序列化为
下面实现的[Serializable]
public class PluginConfiguration : System.Runtime.Serialization.ISerializable
{
public string Name { get; set; }
public PluginConfiguration()
{
}
protected PluginConfiguration(SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new System.ArgumentNullException("info");
Name = (string)info.GetValue("Name", typeof(string));
}
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Name", Name);
}
}
[Serializable]
public class MyPluginConfiguration : PluginConfiguration
{
public string AccessToken { get; set; }
public MyPluginConfiguration()
{
}
protected MyPluginConfiguration(SerializationInfo info, StreamingContext context) :base(info, context)
{
}
}
private class PluginBinder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
return typeof(PluginConfiguration);
}
}
用法:
var c = new PluginConfiguration() { Name = "Name" };
var p = new MyPluginConfiguration() { Name = "Name", AccessToken = "MyToken" };
BinaryFormatter fmt = new BinaryFormatter();
MemoryStream cms = new MemoryStream();
fmt.Serialize(cms, c);
cms.Position = 0;
PluginConfiguration revc = fmt.Deserialize(cms) as PluginConfiguration;
MemoryStream pms = new MemoryStream();
fmt.Serialize(pms, p);
pms.Position = 0;
MyPluginConfiguration prev = fmt.Deserialize(pms) as MyPluginConfiguration;
//given a stream containing the serialization of MyPluginConfiguration
// serailize it as a the known PluginConfiguration Type
pms.Position = 0;
fmt.Binder = new PluginBinder();
PluginConfiguration PluginFromCustomStream = fmt.Deserialize(pms) as PluginConfiguration;