l33t
l33t

Reputation: 19937

How do you deserialize an interface to an internal class of another assembly?

Obviously, it is impossible to serialize/deserialize interfaces if the concrete types are not known to the compiler.

I have an interface-only assembly MyInterfaces and an assembly MyImpl with internal implementations of these interfaces. Instantiation looks like this:

MyInterfaces.IFoo foo = MyImpl.FooFactory.CreateFoo();

Here's the factory in assembly MyImpl:

IFoo CreateFoo()
{
    return new Foo(); // Internal class!
}

And here's the concrete Foo class in assembly MyImpl:

[DataContract]
internal class Foo : IFoo
{
    [DataMember]
    public string Bar
    {
        get;
        set;
    }
}

Serialization is trivial

Reading the type of the factory-created IFoo object allows for serialization of the IFoo interface:

var serializer = new DataContractSerializer(typeof(MyFooContainer),
    new Type[] { container.Foo.GetType() });
serializer.WriteObject(writer, container);

Deserialization impossible?

When deserializing, the type cannot be deduced since we have no object to look at!

var serializer = new DataContractSerializer(typeof(MyFooContainer),
    new Type[] { /* CANNOT provide other assembly's internal type! */ });
container = (MyFooContainer)serializer.ReadObject(reader);

I was hoping that the serialized XML would be enough for DataContractSerializer to determine how to create the MyImpl.Foo object, but no. It tells me this:

"Error in line 1 position 269. Element 'http://schemas.datacontract.org/2004/07/MyAssembly:Foo' contains data from a type that maps to the name 'http://schemas.datacontract.org/2004/07/MyImpl:Foo'. The deserializer has no knowledge..."

Q: Using DataContractSerializer, how do you deserialize an interface to an internal, derived class of another assembly?

Obviously, it makes sense to have public interfaces with internal implementations. It also makes sense to allow for serialization. Please help!

More about this particular problem: http://blogs.msdn.com/b/sowmy/archive/2008/10/04/serializing-internal-types-using-xmlserializer.aspx

Upvotes: 2

Views: 1469

Answers (2)

YK1
YK1

Reputation: 7602

I think you are defeating the purpose of DataContractSerializer by cheating it into serializing non-public data. The design of DataContractSerializer is such that it is meant to serialize publicly visible and sharable data only. This helps achieve platform and technology independence by making it possible to share the type information in formats like WSDL.

For the functionality you are looking to achieve - it is better to use BinaryFormatter. However, then you are stuck with only .NET for de-serialization.

Upvotes: 3

nvoigt
nvoigt

Reputation: 77285

You could let the factory that delivers the instances of your interface have another method to deliver a serializer to serialize/deserialize the objects. That way, the serializer can know all the internal classes.

Upvotes: 3

Related Questions