2

我有一个 dll 库 TaskLibrary.dll ,其中一个类Execution执行一些Operation(s)和一个类,该类ParallelizeExecution需要一个Execution,克隆它并执行Run多个Execution实例的方法。

该类的Clone方法Execution通过转换Executionin xml 并将其恢复为正常作为新实例来工作

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{
    ...
}

Now I have a new project referencing the TaskLibrary.dll. I need to add a new kind of Operation to a Execution:

public class Operation3: Operation2 {
}

Everything works fine with a single execution, but when I use ParallelizeExecution Operation3 is correctly serialized as Operation2 thus executing an unwanted Run method. How can I add a new type of AOperation to the Execution class and expect it to be correctly serialized and run in the Execution?

OR

How can I avoid the problem without altering the way the Execution class is serialized?

Caveat: I know that it is possible to use Reflection to xmlserialize any tipe extending a given one, but i'd rather learn how to do this using standard OOP (if possible).

EDIT: I could modify TaskLibrary.dll but I'd rather avoid this approach, it would void my efforts in learning new things and aiding the community, moreover it would be quite painful to redistribute the library to those already using it.

4

1 回答 1

1

You can use the extraTypes argument to the XmlSerializer constructor. Use reflection to find all of the relevant types, and create the XmlSerializer with the complete list. The overall process is laid out here, but for posterity's sake:

// 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());
于 2012-05-31T15:18:37.990 回答