2013-09-19 2 views
3

У меня есть ряд статических классов репозитория, которые хранят и извлекают объекты данных. Я хочу предоставить им некоторые общие функции, поэтому я наследую их от абстрактного класса.Дизайн статических классов с общей функциональностью через наследование

Это не работает, поскольку статические классы не допускаются к наследованию. Я верю в .NET-проект, поэтому я согласен с тем, что это по уважительной причине.

Итак, это заставляет меня поверить, что здесь есть некоторые фундаментальные проблемы с дизайном.

Вопрос: как мне создать свой код для достижения результата, который я ищу? Или это просто вопрос о том, чтобы повторить методы во всех моих классах. Возможно, синглтон?

Static Repo:

public static class CreditMemos : InvoiceRepository<CreditMemo> 
{ 
    public static List<CreditMemo> GetByDocumentNumber(string documentNumber) 
    { 
     return CheckCache(
      ConvertReaderToCreditMemos(
       Invoices.GetByDocumentNumber<CreditMemo>(documentNumber))); 
    } 
} 

Желаемая Основание:

abstract class InvoiceRepository<t> 
    where t: DataObjects.Invoice 
{ 
    static List<t> invoiceCache = new List<t>(); 

    static protected List<t> CheckCache(List<t> results) 
    { 
     foreach (var result in results) 
      if (!invoiceCache.Any(p => p.ID == result.ID)) 
       invoiceCache.Add(result); 
     return invoiceCache.Where(p => results.Any(a => a.ID == p.ID)).ToList(); 
    } 
} 
+3

Вы могли бы рассмотреть возможность использования инъекции зависимостей, которые могли бы позволить вам использовать один экземпляр нестатический репозиторий легче. – blins

+0

И вот почему существуют синглтоны. – Will

+0

Если вы вообще интересуетесь об модульном тестировании, используйте инъекцию зависимости интерфейса. Это значительно облегчит вам жизнь. –

ответ

4

Вы можете просто уронить static из ваших классов, наследующих, и заставить их работать так же, скрывая конструктор:

public sealed class CreditMemos : InvoiceRepository<CreditMemo> 
{ 
    private CreditMemos() { } 
    ... 

Или вы можете сделать InvoiceRepository<t> свои static class, и вместо унаследования вы просто используете методы в своих других static class es. (Кстати, по соглашению с заглавной буквы всех имен типов, в том числе родовых типов, так T, не t)

public static class CreditMemos 
{ 
    public static List<CreditMemo> GetByDocumentNumber(string documentNumber) 
    { 
     return InvoiceRepository<CreditMemo>.CheckCache(new List<CreditMemo>()); 
    } 
} 
public static class InvoiceRepository<T> 
    where T: DataObjects.Invoice 
{ 
    static List<T> invoiceCache = new List<T>(); 

    static internal List<T> CheckCache(List<T> results) 
    { 
     foreach (var result in results) 
      if (!invoiceCache.Any(p => p.ID == result.ID)) 
       invoiceCache.Add(result); 
     return invoiceCache.Where(p => results.Any(a => a.ID == p.ID)).ToList(); 
    } 
} 
+0

Я просто переработал один сингл, я даже не подумал о том, чтобы скрывать конструктора. Это может сработать нормально ... информации о состоянии, хранящейся в самом репо, нет. Также - спасибо за указатель на Т. Я думал об этом с точки зрения параметра. – Michael

Смежные вопросы