Я решил проблему, удалив этот код из файла .csproj
:
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target>
Я считаю, что чем больше вы начинаете разрабатывать с использованием шаблонов проектирования, тем чаще и чаще вы найдете там, где находится композиция собирается быть привилегированным по наследству. Я действительно верю в книгу Head First: Design Patterns , что « Favor Composition Over Inheritance » является одним из основных принципов проектирования.
Ваш пример возможности макетировать детали композиции для тестирования, вероятно, является одним из лучших возможных примеров.
Редактировать : Хотя основной принцип в шаблонах проектирования - отдавать предпочтение композиции, а не наследованию, это не означает, что не существует шаблонов проектирования, которые используют наследование там, где это нужно. Другой базовый пример - шаблон декоратора,
Книга «Банды четырех» «Шаблоны проектирования» , в основном, посвящена тому, почему предпочитать композицию, а не наследование, и предлагает множество способов сделать это. Некоторые причины:
«Композиция объектов Favour по сравнению с наследованием классов» на самом деле из книги GoF. Этот разговор с Эрихом Гаммой описывает эту идею из книги.
Одним важным шаблоном, который требует наследования, является шаблон шаблонного метода. Этот шаблон широко используется очень удобно, поэтому наследование здесь, чтобы остаться. Другим распространенным шаблоном, который использует наследование, является шаблон Composite. Суть, которую я пытаюсь подчеркнуть, заключается в том, что вообще не стоит сбрасывать со счетов наследование, но я надеюсь, что это все равно ясно, если взглянуть на столько распространенных API-интерфейсов ...
Это не та или иная ситуация. Они не конкуренты.
Наследование также достаточно легко для модульного тестирования. Однако иногда для проверки абстрактного суперкласса требуются фиктивные конкретные классы.
Наследование может быть использовано неправильно. Некоторые проекты выглядят как ситуации «есть», но на самом деле это не так - они более тонкие. Иногда это действительно «ведет себя как», когда вам нужна какая-то композиция (например, стратегия ), чтобы отделить поведение от других атрибутов.
Я думаю, что главная причина, почему состав проще тестировать, заключается в том, что наследование (реализация) имеет тенденцию создавать очень связанные классы, которые они более хрупкие (хрупкий базовый класс) и их сложнее тестировать изолированно.
Наследование определенно имеет свои применения, но я все чаще и чаще предпочитаю композицию наследованию.