我有一个dll库TaskLibrary.dll,其中一个Execution
类正在执行一些Operation
和一个类ParallelizeExecution
,只需一个Execution
,就可以克隆它执行多个Run
实例的Execution
方法。
Clone
类的Execution
方法通过转换xml中的Execution
并将其恢复为正常作为新实例来实现
public Execution{
List<AOperation> operations;
public Run(){
foreach(var op in operations){
//...do stuff...
}
}
public Execution Clone(){
MyXmlSerializer.DeserializeObject<Execution>(
MyXmlSerializer.SerializeObject(this));
}
}
public ParallelizeExecution{
List<Execution> toRun;
public RunParallel(Execution e,int numExecutions){
toRun=new List<Execution>();
for(var i=0;i<numExecutions;i++){
toRun.Add(e.Clone());
}
}
}
Execution
类是可序列化的,每个实现Operation
的类都是可序列化的。这是通过使用所有AOperation
实现扩展的抽象类(IOperation
)获得的,使用XmlInclude
注释使MyXmlSerializer
适用于每个IOperation
。
[XmlInclude(typeof(Operation1))]
[XmlInclude(typeof(Operation2))]
public abstract class AOperation:IOperation{
...
}
现在我有一个引用TaskLibrary.dll的新项目。我需要在Execution
:
public class Operation3: Operation2 {
}
一次执行一切正常,但是当我使用ParallelizeExecution
时,Operation3
被正确序列化为Operation2
,从而执行了不需要的Run
方法。如何向AOperation
类添加新类型的Execution
,并期望它能够正确序列化并在Execution
中运行?
或
如何在不改变Execution
类序列化的方式的情况下避免出现问题?
警告:我知道可以使用Reflection来xmlserialize任何扩展给定的tipe,但我宁愿学习如何使用标准OOP(如果可能的话)这样做。
编辑:我可以修改TaskLibrary.dll,但我宁愿避免这种方法,它会使我学习新事物和帮助社区的努力无效,而且重新分配这些内容会非常痛苦。那些已经使用它的库。
答案 0 :(得分:1)
您可以使用XmlSerializer constructor的extraTypes参数。使用反射查找所有相关类型,并使用完整列表创建XmlSerializer。整个过程是here,但为了后人的目的:
// use reflection to get all derived types
List<type> knownTypes = new List<type>();
// Iterate over whichever assembly has your types.
foreach(Type t in Assembly.GetExecutingAssembly().GetTypes())
if (typeof(Car).IsAssignableFrom(t) ||
typeof(Wheel).IsAssignableFrom(t) ||
typeof(Door).IsAssignableFrom(t))
knownTypes.Add(t);
// prepare to serialize a car object
XmlSerializer serializer = new XmlSerializer(typeof(Car), knownTypes.ToArray());