CsTestShop
Раздел с примерами из C#-проекта CsTestShop — gRPC-магазина на .NET 10 с PostgreSQL и Kafka.
Оба примера — про репозитории: интерфейсы, их реализации и то, как DI-контейнер подставляет одно вместо другого.
Примеры
- IProductRepository — согласованный контракт с одной брешью.
- IUserRepository — правильная подстановка через DI. Отдельно разбирается, почему WIP-методы не считаются нарушением LSP.
Что показывает CsTestShop
Оба примера иллюстрируют одну и ту же мысль с разных сторон:
LSP — это не только про иерархии классов. Это про любую подстановку: интерфейс + реализация, абстракция + конкретика. DI-контейнер — это техническая точка, где подстановка происходит. Если она безопасна (клиент не замечает разницы) — LSP соблюдён. Если нет — нарушен.
В IProductRepository мы показываем случай, когда контракт соблюдён формально
(сигнатуры совпадают), но нарушен по поведению (разные методы ведут себя
по-разному при отсутствии записи). В IUserRepository — противоположный случай:
контракт соблюдён целиком, и подстановка работает без сюрпризов.
Отдельный нюанс, который часто путают: NotImplementedException — это не
нарушение LSP, а WIP. Незавершённый код не анализируется принципом
подстановки. Когда методы будут дописаны, они либо будут соответствовать
контракту, либо нет — и только тогда можно будет делать выводы.