当只有接口可用时如何反序列化?

时间:2013-08-26 04:05:12

标签: c# .net serialization deserialization binary-deserialization

我有三个组成部分:

  • 实用程序库(Processor.dll):只知道元素库
  • 元素库(IElement):不知道任何库
  • App:了解两个库

App调用Processor库并向其传递一个类型:

ClassA : IElement

ClassA在传递给Processor之前被序列化。 Processor是一个基础库,不了解ClassA等类类型。它确实知道IElement。处理器将反序列化传递给它的IElement,它是ClassA类型。

问题是无法反序列化接口。但处理器不了解ClassA,不应该。在这种情况下,如何获得对传入对象的引用?

1 个答案:

答案 0 :(得分:1)

处理此问题的一种方法是创建一个加载classA的SerializationBinder实现,然后将对binder的实例的引用传递给Processor.dll,以便Processor.dll可以使用您的binder实现进行反序列化。这将允许您在App模块中保留引用ClassA的代码(当然,必须在App模块中定义SerializationBinder实现)。

这是一个例子:在Element库中给出这个接口

public interface IElement
{
    string DoSomething(string param);
}

你会像这样定义你的处理器:

public class ProcessorClass
{
    private SerializationBinder _binder;

    public ProcessorClass(SerializationBinder binder)
    {
        _binder = binder;
    }

    public string CallDoSomething(Stream s)
    {
        var formatter = new BinaryFormatter();

        formatter.Binder = _binder;

       var i = (IElement)formatter.Deserialize(s);

        return i.DoSomething("the processor");
    }
}

在这个例子中,我使用的是一个非常非常简单的序列化绑定器。请注意,这必须在App程序集中定义,这就是除了App之外你不需要引用ClassA的原因。

class Binder : SerializationBinder
{
    //WARNING: demonstration only, DO NOT USE in production code
    public override Type BindToType(string assemblyName, string typeName)
    {
        return Type.GetType("ClassA");
    }
}

然后我们在App程序集中将它们整合在一起:

var ms = new MemoryStream();

var formatter = new BinaryFormatter();

var theObject = new ClassA();

formatter.Serialize(ms, theObject);

var processor = new ProcessorClass(new Binder());

ms.Seek(0, SeekOrigin.Begin);

string result = processor.CallDoSomething(ms);

有关SerializationBinder的另一个示例,请参阅此This MSDN example