Я пробовал архитектуру SOLID в своем последнем проекте.
У меня есть интерфейс под названием ILog и класс Log, который реализовал ILog. (Насколько я понимаю, это должно быть сделано, чтобы следовать принципу открытия / закрытия)
Чтобы оставаться открытым для расширений, я реализовал интерфейс через List<ILog> вместо твердой реализации List<Log>.
Сериализация List<ILog> не проблема, а вот десериализация - нет. Я, конечно, понимаю, почему, потому что десериализатор не знает, какой класс реализации он должен использовать.
Вопрос: Как узнать, в какой конкретный тип десериализовать объект, сериализованный через ссылку на интерфейс?
Почему вы хотите сериализовать регистратор? Или, в более общем смысле, почему вы используете интерфейс, в котором хотите (де) сериализовать что-то? Вы не можете десериализовать сериализованный FooFrobber как BarFrobber, даже если они оба реализуют IFrobber.
Я подумал, что было бы неплохо оставаться открытым для будущих расширений, так как этот проект будет существовать еще довольно долго.
Почему бы не потребовать, чтобы разработчик ILog также реализовал десериализацию? В конце концов, они лучше всех знают свой имп.
На самом деле это был не класс Log - для простоты я выбрал простое слово ...
Расширяемость, интерфейсы и сериализация не связаны друг с другом. Пожалуйста, задайте очень конкретный вопрос, поскольку это звучит слишком расплывчато. Если, например, ваш вопрос - «Как узнать, в какой конкретный тип десериализовать объект, сериализованный через ссылку на интерфейс», ответ может быть "Сохраните информацию о Type при сериализации".
@CodeCaster Да, я думаю, это может быть ответом! Соответственно обновлю свой вопрос спасибо! Вы хотите изменить свой комментарий на ответ, чтобы я мог отметить его соответствующим образом?
Полный ответ в некоторой степени зависит от сериализатора, который вы используете. Например, JSON.NET имеет встроенные методы для этого типа вещей., и если вы используете WCF, есть другой метод и т. д.





Serializing the List is no problem, but deserializing is.
Если вы десериализуете, вам обязательно нужно каким-то образом сообщить своему сериализатору, какое конкретное представление вашего интерфейса использовать. В случае Json.NET вы можете использовать JsonConstructorAttribute (см. Также этот ответ) или резолверы в сочетании с внедрением зависимостей.
Question: What does it help me to work with List if I have to define the specific implementation-class for data storage / data import anyways?
Интерфейсы отделяют ваш код от фактической реализации, что дает различные преимущества. Например, с точки зрения модульного тестирования они упрощают имитацию (поскольку вы можете удовлетворить интерфейс с имитацией экземпляра, вместо того, чтобы заставлять использовать «настоящий» класс). Кроме того, интерфейсы позволяют получить выгоду от ковариация / контравариантность, чего у вас не было бы с классами в C#. Для получения дополнительной информации о преимуществах интерфейсов ознакомьтесь с различными ответами на вопрос это или прочтите сообщение в блоге это.
Как было сказано выше, интерфейсы всегда вводят определенный уровень накладных расходов / абстракции, и вам необходимо оценивать каждый случай / ситуацию, имеют ли они смысл или нет.
What would be the best way to handle the data-storage of interface objects or are they only used at runtime?
Вам обязательно нужно хранить конкретные представления, а это означает, что во время сохранения вам необходимо решить, какую конкретную реализацию использовать для хранения (а затем десериализации).
Такие рекомендации, как SOLID, не принесут вам никакой пользы, если они не соответствуют вашим потребностям. Вопрос, на который нужно ответить, заключается не в том, следуете ли вы твердым принципам; действительно ли вам нужен этот интерфейс
ILogили нет.