Шаблон репозитория для доступа к текстовому файлу - PullRequest
4 голосов
/ 30 ноября 2011

Я довольно новичок в шаблоне репозитория, и я хотел бы сделать это правильно. Я также пытаюсь использовать Inversion of Control (также новый).

Я хотел бы убедиться, что я правильно использую шаблон репозитория.

Я взял это как пример базового интерфейса для моих репозиториев.

public interface IRepository<T> where T : class
{
    IEnumerable<T> Find(Expression<Func<T, bool>> where);

    IEnumerable<T> GetAll();

    void Create(T p);

    void Update(T p);
}

IPaymentRepository предназначен для расширений IRepository (хотя я не понимаю, зачем мне это нужно, если у меня есть метод Find выше)

public interface IPaymentRepository : IRepository<Payment>
{
}

PaymentRepository просто читает текстовый файл и создает POCO.

public class PaymentRepository : IPaymentRepository
{
    #region Members

    private FileInfo paymentFile;
    private StreamReader reader;
    private List<Payment> payments;

    #endregion Members

    #region Constructors

    #endregion Constructors

    /// <summary>
    /// Initializes a new instance of the <see cref="PaymentRepository"/> class.
    /// </summary>
    /// <param name="paymentFile">The payment file.</param>
    public PaymentRepository(FileInfo paymentFile)
    {
        if (!paymentFile.Exists)
            throw new FileNotFoundException("Could not find the payment file to process.");

        this.paymentFile = paymentFile;
    }

    #region Properties

    #endregion Properties

    #region Methods

    public IEnumerable<Payment> Find(Expression<Func<Payment, bool>> where)
    {
        throw new NotImplementedException();
    }

    /// <summary>
    /// Gets all payments from payment file.
    /// </summary>
    /// <returns>Collection of payment objects.</returns>
    public IEnumerable<Payment> GetAll()
    {
        this.reader = new StreamReader(this.paymentFile.FullName);
        this.payments = new List<Payment>();

        while (!reader.EndOfStream)
        {
            string line = reader.ReadLine();
            Payment payment = new Payment()
            {
                AccountNo = line.Substring(0, 11),
                Amount = double.Parse(line.Substring(11, 10))
            };

            this.payments.Add(payment);
        }

        return this.payments;
    }

    public void Create(Payment p)
    {
        throw new NotImplementedException();
    }

    public void Update(Payment p)
    {
        throw new NotImplementedException();
    }

    #endregion Methods

Я хотел бы знать, как реализовать метод Find. Я предполагаю, что я бы вызвал GetAll и построил внутренний кеш в хранилище. Например, я хотел бы найти все учетные записи, платежи которых превышают 50 долларов США.

1 Ответ

1 голос
/ 30 ноября 2011

С вашей текущей подписью IRepository вы бы реализовали это так:

public IEnumerable<Payment> Find(Expression<Func<Payment, bool>> where)
{
    this.reader = new StreamReader(this.paymentFile.FullName);
    this.payments = new List<Payment>();

    while (!reader.EndOfStream)
    {
        string line = reader.ReadLine();
        Payment payment = new Payment()
        {
            AccountNo = line.Substring(0, 11),
            Amount = double.Parse(line.Substring(11, 10))
        };
        if (where(payment) 
        {
           this.payments.Add(payment);
        }
    }

    return this.payments;
}

Однако, если ваша системная память позволяет, вы можете сохранить кэшированный список (из GetAll ()) и использовать Find () в списке. Это должно быть на порядок быстрее в зависимости от размера вашего списка.

...