Чи перешкоджає серіалізація використання ін'єкційної залежності?


9

Просте запитання: я розумію, що серіалізація в C # вимагає конструкторів за замовчуванням. Це дозволить виключити можливість використання DI, що вводиться конструктором (що, як правило, є вподобаним стилем DI в моєму читанні [потрібне цитування] ). Так це насправді або ситуація, або я щось пропускаю?

(Побічне запитання): Чи контейнери IoC якимось чином відступають від цього компромісу?


This would eliminate the possibility of using Constructor injected DI- Чому? Ви все ще можете мати параметризованих інструкторів, якщо ви включаєте конструктор за замовчуванням для цілей серіалізації (конструктор за замовчуванням може бути приватним, якщо хочете).
Роберт Харві

@RobertHarvey: Я відчуваю себе трохи щільно, але я не дуже тебе розумію. Що таке "параметризований інструктор"? (помилка?) Після десеріалізації об’єкта я не можу його сконструювати знову. Чи пропонуєте ви використовувати введення властивостей / налаштувань для об'єкта, що споживається за замовчуванням?
kmote

1
Параметризований конструктор - це один із параметрами. Я припускаю, що десеріалізація відбувається за даними, отриманими від об'єкта, який був правильно побудований за допомогою ін'єкції залежності. Вам не доведеться конструювати об’єкт під час десеріалізації; вона вже будувалася раніше.
Роберт Харві

1
Ні, ти не помилився. Ось як це працює. Подумайте про це як задні двері. Ви не отримаєте жодної перевірки, але вона буде працювати. Зауважте, що BinaryFormatter та DataContractSerializer не потребують конструкторів за замовчуванням.
Роберт Харві

1
Щоб було зрозуміло, все десеріалізація - це заповнити стан у вашому об'єкті значеннями, які вказані в XML-об'єкті. Для цього він використовує Reflection і обходить будь-яку форму логіки перевірки конструктора, тому з точки зору DI це обман, якщо ті значення XML спочатку не надходили від об'єкта, побудованого за допомогою звичайного DI.
Роберт Харві

Відповіді:


6

Неможливо десериалізувати об’єкт, а також ввести залежність до іншого, вже існуючого об'єкта, за один крок у C #, використовуючи стандартні механізми серіалізації. Натомість вам доведеться використовувати властивість введення властивостей, спочатку сконструюючи об'єкт за допомогою десеріалізатора, після чого вводячи залежність. Для більшості реальних програм я не вважаю це сприятливим недоліком - якщо у вас модель серіалізованих моделей даних, яка також має залежність від інших класів моделей, що не належать до даних, слід перевірити, чи може у вашому класі даних даних бути занадто багато обов'язків уже.

Якщо це насправді вас турбує, ви можете розглянути питання про те, щоб обернути свій серіалізаційний об’єкт класом декораторів, де ви можете передати де-серіалізатор та додаткові залежності через конструктор. Потім ця обгортка виконує два етапи (де-серіалізація загорнутого об'єкта та введення властивостей) у своєму конструкторі.


1

Я вирішую цю проблему так: впорскування фабрик залежностей. На цих заводах спочатку вирішують залежність, оскільки вона зареєстрована в контейнері, а потім "дезаріалізує" всі решта даних: json.net дозволяє заповнити поля в існуючому об'єкті.

Оскільки заводський код поєднується з кодом підключення контейнера IoC, я не думаю, що використання container.Resolveвсередині заводу порушує правило, яке containerпотрібно використовувати лише в одному місці в коді: там, де відбувається вся електропроводка.

На сьогоднішній день я намагаюся зробити цей процес автоматичним (на відміну від того, на що я тестував цей підхід), використовуючи рефлексію. Так, не дуже багато того, що залишається від самої деріаріалізації json.net, частина її замінена спеціальним кодом, але я думаю, чому це турбує.

Також, якими були ваші остаточні думки / рішення з цього питання? Прочитавши цю публікацію, я бачу два способи: дезаріалізувати, потім ввести; або ввести, потім дезаріалізувати (заповнити). І я все-таки знаходжу свій спосіб краще. Буду радий почути аргументи на противагу цьому (я вважаю, що мій шлях може бути кращим для моєї справи, але я не можу наочно уявити хороші альтернативні випадки, де це не вдається, лише деякі незначні здогадки)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.