dimanche 28 juin 2015

How to Abstract Creation of Singleton Using XML Serialization

I'm trying to create a generic repository using the Singleton pattern which persists to an XML file. There are currently 3 concrete repositories, each of which are loaded from different XML files. I cannot figure out how to properly abstract the creation of the repository from the XML file. Here are my classes for one implementation of this repository.

Models

public interface IEntity
{
    string Name { get; }
}

public class Game : IEntity
{
    [XmlElement("Name")]
    public string Name { get; set; }

    [XmlElement("ExecutablePath")]
    public string ExecutablePath { get; set; }

    private Game() { } // Required for XML serialization.

    public Game(string name, string executablePath)
    {
        Name = name;
        ExecutablePath = executablePath;
    }
}

Repository

public interface IRepository<TEntity> where TEntity: IEntity
{
    List<TEntity> Items { get; }

    void Add(TEntity entity);
    void Delete(TEntity entity);
}

public abstract class Repository<TEntity> : IRepository<TEntity> where TEntity : IEntity 
{
    public abstract List<TEntity> Items { get; set; }

    private static Repository<TEntity> _instance;
    public static Repository<TEntity> Instance
    {
        get
        {
            if (_instance == null)\
                _instance = RepositoryFactory<Repository<TEntity>>.LoadFromFile();

            return _instance;
        }
    }

    public void Add(TEntity entity)
    {
        Items.Add(entity);
    }

    public void Delete(TEntity entity)
    {
        Items.Remove(entity);
    }
}

public static class RepositoryFactory<TRepository> 
{
    public static TRepository LoadFromFile() 
    {
        using (TextReader reader = new StreamReader("Games.xml"))
        {
            XmlSerializer serializer = new XmlSerializer(typeof(TRepository));
            return (TRepository)serializer.Deserialize(reader);
        }
    }
}

[XmlRoot("Games")]
public class GameRepository : Repository<Game>
{
    [XmlElement("Game")]
    public override sealed List<Game> Items { get; set; }

    private GameRepository()
    {
        Items = new List<Game>();
    }
}

When trying to call 'GameRepository.Instance', I get this very generic exception: {"<Games xmlns=''> was not expected."}

This is admittedly one of my first times trying to gel these design patterns (singleton/factory) together, so this approach may have been completely wrong from the start. I can't diagnose exactly what is wrong from the exception (inner exception is null), so I'm hoping someone who knows these patterns can help me out.

Aucun commentaire:

Enregistrer un commentaire