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