What Was I Thinking?

Follies & Foils of .NET Development
posts - 86 , comments - 254 , trackbacks - 0

How to Serialize an Interface using the XMLSerializer

The short answer is you can't.  At least not without some trickery and giving the serializer some help, and even then it's not pretty.

Here's the plain-jane implementation.  Note:  The following snippet WILL NOT WORK

public interface IWorker
  {
      string WorkerName { get; set; }
  }

  [Serializable]
  public class ImplementedWorker:IWorker
  {
      #region IWorker Members
      public string WorkerName { get; set; }
      #endregion
  }

  [Serializable]
  public class WorkToDo
  {
      public IWorker Worker;
  }

public void Tryme()
{
    WorkToDo workToDo = new WorkToDo();
    workToDo.Worker =  new ImplementedWorker();

}

If you try to serialize the WorkToDo class, you'll get the "cannot serialize Worker because IWorker is an interface" exception. This makes sense when you consider the XML serializer will have to deserialize this into some concrete type.

So let's give it a type.  since we don't want to lose the ability to enforce the implementation of our interface properties, we're going to make an Abstract class.

  public interface IWorker
  {
      string WorkerName { get; set; }
  }
  [Serializable]
  public abstract class WorkerBase : IWorker
  {
      public abstract string WorkerName { get; set; }
  }

  [Serializable]
  public class ImplementedWorker : WorkerBase
  {
      #region IWorker Members
      public override string WorkerName { get; set; }
      #endregion
  }
  [Serializable]
  public class WorkToDo
  {
      public WorkerBase Worker;
  }

Notice that we  change the defintion of the implementation class(ImplementedWorker) from the interface to the abstract class. we're almost there, but the serializer still can't deserialize this to a concrete type.  This is where we have to give the serializer some help in the form of the XMLIncludeAttribute.  The XMLIncludeAttribute tells the serializer "this thing might be this concrete type", you can stack multiple XMLInclude attributes on your abstract class definition, and during serialization, it figures out the correct concrete type to use.

   public interface IWorker
   {
       string WorkerName { get; set; }
   }

   [Serializable]
   [XmlInclude(typeof(ImplementedWorker))]
   public abstract class WorkerBase : IWorker
   {
       public abstract string WorkerName { get; set; }
   }

   [Serializable]
   public class ImplementedWorker : WorkerBase
   {
       #region IWorker Members
       public override string WorkerName { get; set; }
       #endregion
   }
   [Serializable]
   public class WorkToDo
   {
       public WorkerBase Worker;
   }

WorkToDo will now properly serialize using the XMLSerializer. Here's the downside (and its a biggie), every time you add a new subclass of your abstract class, you've got the remember to add another XMLInclude attribute for it in the abstract class definition. I told you it wasn't going to be pretty. 

An alternate approach would be to write your own custom serializer for the type, but that's a post for a different day.

 

 

Print | posted on Wednesday, January 16, 2008 10:17 AM | Filed Under [ Visual Studio ]

Feedback

Gravatar

# re: How to Serialize an Interface using the XMLSerializer

This still doesn't actually serialize an interface; it's still vanilla serialization of implemented types.
The point of an interface is that you can implement the interface and inherit from separate base class. With this approach, you are locked into inheriting everything from WorkerBase.
6/13/2008 1:13 PM | Koush
Gravatar

# re: How to Serialize an Interface using the XMLSerializer

You are correct. As stated in the first line of the post:
"How to Serialize an Interface using the XMLSerializer
The short answer is you can't. "

I was able to serialize the interface directly but had to write my own serializer to do the job, which destroys the interoperability of the solution.
7/6/2008 12:45 AM | wtfChris
Gravatar

# re: How to Serialize an Interface using the XMLSerializer

it does not work!!!
6/12/2009 8:15 AM | Khanh
Gravatar

# re: How to Serialize an Interface using the XMLSerializer

What problem are you having with the code?
I just re-created the sample using the above code and it was able to serialze and deserialize the object without issue.
6/12/2009 7:12 PM | wtfChris
Gravatar

# re: How to Serialize an Interface using the XMLSerializer

I have just used the idea to solve me problem. It really works. Thank you.
8/2/2009 2:40 PM | FKotov
Gravatar

# re: How to Serialize an Interface using the XMLSerializer

It worked. Thanks.
9/15/2009 8:15 AM | Justin
Gravatar

# re: How to Serialize an Interface using the XMLSerializer

I ran into the inability of the XMLSerializer to serialize an interface writing a WCF service. The solution there is to simply move your classes out of the interface. But this article got me thinking about the issue correctly.
10/31/2009 5:16 PM | Dave brask
Gravatar

# re: How to Serialize an Interface using the XMLSerializer

thanks for the idea !
3/25/2011 7:54 AM | xx
Gravatar

# re: How to Serialize an Interface using the XMLSerializer

That is the pretty good solution.
Thanks.
12/4/2013 9:20 AM | Serge
Post A Comment
Title:
Name:
Email:
Comment:
Verification:
 
 

Powered by: