WebService --> XML Cache Repository I'm working on a small application that uses a WebService to get meta-data about television episodes.  What I'd like to do is start building out a local cache of the series so that I can reduce the number of calls to the service.  Data being stale is not a concern at all for this case.  I've chosen to use an XML file to implement the local repository.

Here's the code:

public interface IVideo { int SeriesId { get; set; } string Name { get; set; } }

public class TVShow : IVideo { public int SeriesId { get; set; } public string Name { get; set; } }

public class IVideoCollection : List&lt;IVideo&gt;, IXmlSerializable
{
    public IVideoCollection() : base() { }

    #region IXmlSerializable
    public System.Xml.Schema.XmlSchema GetSchema() { return null; }

    public void ReadXml(XmlReader reader)
    {
        reader.ReadStartElement("IVideoCollection");
        while (reader.IsStartElement("IVideo"))
        {
            Type type = Type.GetType(reader.GetAttribute("AssemblyQualifiedName"));
            XmlSerializer serial = new XmlSerializer(type);

            reader.ReadStartElement("IVideo");
            this.Add((IVideo)serial.Deserialize(reader));
            reader.ReadEndElement();
        }
        reader.ReadEndElement();
    }

    public void WriteXml(XmlWriter writer)
    {
        foreach (IVideo vid in this)
        {
            writer.WriteStartElement("IVideo");
            writer.WriteAttributeString("AssemblyQualifiedName", vid.GetType().AssemblyQualifiedName);
            XmlSerializer xmlSerializer = new XmlSerializer(vid.GetType());
            xmlSerializer.Serialize(writer, vid);
            writer.WriteEndElement();
        }
    }
    #endregion
}

public class SeriesRepository
{
    public IVideoCollection Collection;
    public string RepoPath {get;set;}

    public SeriesRepository()
    {
        Collection = new IVideoCollection();
        RepoPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "IVideoCollection.xml");
        if (File.Exists(RepoPath))
        {
            var xmlSerializer = new XmlSerializer(Collection.GetType());
            var xmlReader = XmlReader.Create(new StreamReader(RepoPath));
            Collection = (IVideoCollection)xmlSerializer.Deserialize(xmlReader);
        }
    }

    public void SaveChanges()
    {
        var xmlSerializer = new XmlSerializer(Collection.GetType());
        StreamWriter writer = new StreamWriter(RepoPath);
        xmlSerializer.Serialize(writer, Collection);
        writer.Flush();
        writer.Close();
    }
}


I'm trying looking to see if there are any obvious points of failure that I haven't seen.  Any feedback is appreciated.

The resulting XML looks like:

&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;IVideoCollection&gt;
  &lt;IVideo AssemblyQualifiedName="MyNamespace.TVShow, MyNameSpace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"&gt;
    &lt;TVShow xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
      &lt;SeriesId&gt;55512345&lt;/SeriesId&gt;
      &lt;Name&gt;This is the show name&lt;/Name&gt;
    &lt;/TVShow&gt;
  &lt;/IVideo&gt;
&lt;/IVideoCollection&gt;
I tend to prefer composition over inheritance, but I see why you inherited from List&lt;T&gt;, and I feel like it's okay, but you'll run into some trouble if you decide that some other type of collection would be better suited to your task. I would spend a little time thinking about what you'd need to do in your client code if you changed the implementation. It may be worth implementing IList by delegating to a private instance of List&lt;IVideo&gt;. Then again, it may not be. 

XmlSerializer and StreamWriter both implement IDisposable, so it'd be better to put your usages of these into a using block. For example:

public void SaveChanges()
{
    using (var xmlSerializer = new XmlSerializer(Collection.GetType()))
    using (StreamWriter writer = new StreamWriter(RepoPath))
    {
        xmlSerializer.Serialize(writer, Collection);
    }
}