What Was I Thinking?

Follies & Foils of .NET Development

  Home  |   Contact  |   Syndication    |   Login
  74 Posts | 0 Stories | 191 Comments | 0 Trackbacks

News

Archives

Post Categories

Check These Out

Gurus

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.

 

 

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
posted on Wednesday, January 16, 2008 10:17 AM

Feedback

# re: How to Serialize an Interface using the XMLSerializer 6/13/2008 1:13 PM Koush
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.

# re: How to Serialize an Interface using the XMLSerializer 7/6/2008 12:45 AM wtfChris
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.


# re: How to Serialize an Interface using the XMLSerializer 6/12/2009 8:15 AM Khanh
it does not work!!!

# re: How to Serialize an Interface using the XMLSerializer 6/12/2009 7:12 PM wtfChris
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.


# re: How to Serialize an Interface using the XMLSerializer 8/2/2009 2:40 PM FKotov
I have just used the idea to solve me problem. It really works. Thank you.

# re: How to Serialize an Interface using the XMLSerializer 9/15/2009 8:15 AM Justin
It worked. Thanks.

# re: How to Serialize an Interface using the XMLSerializer 10/31/2009 5:16 PM Dave brask
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.

# re: How to Serialize an Interface using the XMLSerializer 3/25/2011 7:54 AM xx
thanks for the idea !

Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: