La serializzazione preclude l'uso dell'iniezione di dipendenza?


9

Domanda semplice: capisco che la serializzazione in C # richiede costruttori predefiniti. Ciò eliminerebbe la possibilità di utilizzare DI iniettato dal costruttore (che è generalmente lo stile preferito di DI, nella mia lettura [citazione necessaria] ). Quindi è davvero una o una situazione o mi sto perdendo qualcosa?

(Domanda a margine): i contenitori IoC fanno da parte in qualche modo questo compromesso?


This would eliminate the possibility of using Constructor injected DI-- Perché? Puoi comunque avere istruttori con parametri, purché includi un costruttore predefinito per scopi di serializzazione (il costruttore predefinito può essere privato, se lo desideri).
Robert Harvey,

@RobertHarvey: mi sento un po 'denso, ma non ti capisco abbastanza. Che cos'è un "istruttore parametrizzato"? (errore di battitura?) Una volta che un oggetto è stato deserializzato, non posso più costruirlo. Stai suggerendo di usare l'iniezione di proprietà / setter su un oggetto costruito per impostazione predefinita?
kmote

1
Un costruttore con parametri è uno con parametri. Sto assumendo qui che la deserializzazione si verifica da dati derivati ​​da un oggetto che è stato correttamente costruito usando l'iniezione di dipendenza. Non è necessario costruire l'oggetto durante la deserializzazione; era già stato costruito prima.
Robert Harvey,

1
No, non ti sbagli. Funziona così. Pensalo come iniezione back-door. Non otterrai alcuna convalida, ma funzionerà. Si noti che BinaryFormatter e DataContractSerializer non richiedono costruttori predefiniti.
Robert Harvey,

1
Per essere chiari, tutta la deserializzazione fa è riempire lo stato nell'oggetto con i valori specificati nell'oggetto XML. Utilizza Reflection per raggiungere questo obiettivo e ignora qualsiasi forma di logica di convalida del costruttore, quindi dal punto di vista di DI, è un imbroglio, a meno che quei valori XML originariamente non provenissero da un oggetto costruito attraverso DI ordinario.
Robert Harvey,

Risposte:


6

Non è possibile deserializzare un oggetto e iniettare una dipendenza a un altro oggetto già esistente, in un passaggio in C #, usando i meccanismi di serializzazione standard. Dovrai invece usare l'iniezione di proprietà, prima costruendo l'oggetto usando il deserializzatore, quindi iniettando la dipendenza. Per la maggior parte delle applicazioni del mondo reale, non lo considero un vero svantaggio: se si dispone di una classe del modello di dati serializzabile, che ha anche dipendenze da altre classi di modelli non di dati, è necessario verificare se la classe del modello di dati potrebbe avere troppe responsabilità già.

Se questo ti disturba davvero, potresti considerare di avvolgere il tuo oggetto serializzabile con una classe decoratore, in cui puoi passare il de-serializzatore e le dipendenze aggiuntive attraverso il costruttore. Quel wrapper esegue quindi i due passaggi (deserializzazione dell'oggetto avvolto e iniezione di proprietà) nel suo costruttore.


1

Sto risolvendo questo problema in questo modo: iniettando fabbriche di dipendenze. In quelle fabbriche, risolvi innanzitutto la dipendenza poiché è registrata nel contenitore, quindi "deserializza" tutti i dati rimanenti: json.net consente di popolare i campi nell'oggetto esistente.

Dato che il codice delle fabbriche va di pari passo con il codice di cablaggio del contenitore IoC, non penso che l'utilizzo container.Resolveall'interno della fabbrica violi la regola, che containerdeve essere utilizzata in un unico punto del codice: dove avviene tutto il cablaggio.

A partire da ora, sto cercando di rendere automatico questo processo (al contrario di quello a cui ho provato quell'approccio) usando la riflessione. Sì, non c'è molto che rimanga dalla deserializzazione di json.net stessa, parte di essa è sostituita da un codice personalizzato, ma penso, perché preoccuparsi.

Inoltre, quali sono stati i tuoi pensieri / decisioni finali in merito? Dopo aver letto questo post vedo due modi: deserializzare, quindi iniettare; o iniettare, quindi deserializzare (popolare). E trovo ancora la mia strada migliore. Saremo lieti di ascoltare argomenti contrari a questo (sto pensando che la mia strada potrebbe essere migliore per il mio caso, ma non riesco a immaginare vividamente buoni casi alternativi, in cui fallisce, solo alcune ipotesi minori)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.