В настоящее время я использую IoC для предоставления конкретных реализаций репозиториев в проекте. Во всех примерах, которые я прочитал, в качестве определения службы используется интерфейс. Однако, прочитав рекомендации Microsoft, рекомендуется предпочесть абстрактные классы интерфейсам .
Я нашел это полезным в сочетании с шаблоном шаблона, чтобы уменьшить повторение. Например, дайте класс Product
со свойством IsActive
. Я мог бы использовать интерфейс для репозитория, например:
interface IProductRepository
{
IEnumerable Load();
}
Если общей задачей является загрузка активных продуктов, мне нужно будет do:
IEnumerable activeProducts = repository.Load().Where(x => x.IsActive);
Где репозиторий
- конкретная реализация. Если бы я использовал абстрактный класс, такой как:
abstract class ProductRepository
{
protected abstract IEnumerable LoadCore();
public IEnumerable Load()
{
return LoadCore().Where(x => x.IsActive);
}
}
Тогда я мог бы загружать активные продукты, используя
IEnumerable activeProducts = repository.Load();
. Вся реализация для загрузки информации о продукте находится в классе contrete, который наследует ProductRepository
, поэтому нет связи с слой стойкости. Если будет обнаружено, что существует другое часто выполняемое действие, то оно может быть добавлено к базовому классу в качестве неразрывного изменения, которое невозможно сделать с использованием интерфейса.
Есть ли какие-либо преимущества в использовании интерфейса вместо абстрактного учебный класс? С какими потенциальными недостатками использования абстрактных классов я мог столкнуться?
Я использую Castle Windsor в качестве контроллера IoC и .Net framework 3.5.