Допустим, у нас есть класс, например SqlIdProvider
, для которого требуется репозиторий SQL для выполнения некоторых операций. У нас также есть класс SqlRepository
, который реализует интерфейс IRepository
следующим образом:
public interface IRepository {
// All repository methods here.
}
public sealed class SqlRepository : IRepository {
// All repository methods here.
}
public sealed class SqlIdProvider {
private IRepository _repository;
public SqlIdProvider(IRepository repository){
_repository = repository;
}
}
* SqlIdProvider
сильно зависит от SqlRepository
, поэтому он не будет работать, если я предоставлю Например, экземпляр следующего класса:
public sealed class MongoRepository : IRepository {
// All repository methods here.
}
Однако подпись SqlIdProvider
говорит мне, что я мог бы просто предоставить один из них, и все должно быть в порядке.
В этом В этой ситуации я обычно думаю о трех вариантах:
1) Сохраняйте как есть и надеюсь, что имени будет достаточно, чтобы другие знали, что вы не должны предоставлять MongoRepository
для SqlIdProvider
(хотя не применяя его каким-либо образом).
2) Измените конструктор SqlIdProvider
, чтобы взять бетон SqlRepository
. Это привело бы к выполнению требования, но это затруднило бы модульное тестирование, заставив нас удалить ключевое слово sealed
из SqlRepository
, чтобы иметь возможность подделать реализацию (кстати, мне нравится, что классы должны быть запечатаны, если нет веской причины не делать этого) .
3) Создайте пустой интерфейс, расширяющий IRepository
, предназначенный для единственной цели SQL хранилищ, называемый ISqlRepository
. Теперь мы могли бы изменить конструктор SqlIdProvider
, чтобы вместо него использовать интерфейс ISqlRepository
.
public interface ISqlRepository : IRepository {
// This one is empty on purpose.
}
Мне кажется, вариант 3) кажется наиболее привлекательным, но все равно кажется, что я делаю что-то не так с созданием пустого интерфейса.
Есть ли лучший способ, которым мы можем быть явными с ограничением и в то же время позволить простое модульное тестирование?