A serialização impede o uso de injeção de dependência?

9

Pergunta simples: Eu entendo que a serialização em C # requer construtores padrão. Isso eliminaria a possibilidade de usar o DI injetado no Constructor (que geralmente é o estilo preferido do DI, na minha leitura [citação necessário] ). Então, é realmente uma situação de um ou outro, ou estou perdendo alguma coisa?

(Pergunta secundária): Os contêineres de IoC evitam essa troca de alguma forma?

kmote
fonte
This would eliminate the possibility of using Constructor injected DI-- Por quê? Você ainda pode ter instrutores parametrizados, desde que inclua um construtor padrão para fins de serialização (o construtor padrão pode ser privado, se desejar).
Robert Harvey
@RobertHarvey: Estou me sentindo um pouco denso, mas não entendo bem você. O que é um "instrutor parametrizado"? (erro de digitação?) Depois que um objeto é desserializado, não consigo construí-lo novamente. Você está sugerindo que eu use a injeção de propriedade / setter em um objeto consagrado por padrão?
kmote
11
Um construtor parametrizado é aquele com parâmetros. Estou assumindo aqui que a desserialização ocorre a partir de dados que foram derivados de um objeto que foi construído corretamente usando injeção de dependência. Você não precisa construir o objeto durante a desserialização; já foi construído antes.
Robert Harvey
11
Não, você não está enganado. É assim que funciona. Pense nisso como injeção na porta traseira. Você não receberá nenhuma validação, mas funcionará. Observe que BinaryFormatter e DataContractSerializer não requerem construtores padrão.
Robert Harvey
11
Para ficar claro, tudo que a desserialização faz é preencher o estado no seu objeto com os valores especificados no objeto XML. Ele usa o Reflection para fazer isso e ignora qualquer forma de lógica de validação de construtor; portanto, da perspectiva do DI, ele é trapaceiro, a menos que esses valores XML originalmente venham de um objeto construído por meio do DI comum.
Robert Harvey

Respostas:

6

Não é possível desserializar um objeto e também injetar uma dependência em outro objeto já existente, em uma etapa do C #, usando os mecanismos de serialização padrão. Você precisará usar a injeção de propriedade, primeiro construindo o objeto usando o desserializador, depois injetando a dependência. Para a maioria dos aplicativos do mundo real, não considero isso uma desvantagem real - se você possui uma classe de modelo de dados serializável, que também depende de outras classes de modelo que não são de dados, verifique se sua classe de modelo de dados pode ter muitas responsabilidades já.

Se isso realmente o incomoda, considere agrupar seu objeto serializável com uma classe decoradora, na qual é possível passar o desserializador e dependências adicionais pelo construtor. Esse wrapper executa as duas etapas (desserialização do objeto empacotado e injeção de propriedade) em seu construtor.

Doc Brown
fonte
1

Estou resolvendo esse problema assim: injetando fábricas de dependências. Nessas fábricas, primeiro resolva a dependência conforme ele é registrado no contêiner e depois "desserialize" todos os dados restantes: json.net permite preencher campos no objeto existente.

Como o código das fábricas acompanha o código de fiação do contêiner de IoC, não acho que o uso container.Resolvedentro da fábrica viole a regra, que containerdeve ser usada apenas em um lugar no código: onde toda a fiação acontece.

A partir de agora, estou tentando tornar esse processo automático (em oposição ao que venho testando essa abordagem) usando reflexão. Sim, não há muito o que resta da própria desserialização do json.net, parte dela é substituída pelo código personalizado, mas acho que por que me preocupar.

Além disso, quais foram seus pensamentos / decisões finais sobre o assunto? Depois de ler este post, vejo duas maneiras: desserializar e injetar; injetar e desserializar (preencher). E ainda acho que meu caminho é melhor. Ficarei feliz em ouvir argumentos contrários a isso (estou pensando em que meu caminho pode ser melhor para o meu caso, mas não consigo imaginar vividamente bons casos alternativos, onde falham, apenas algumas suposições).

jungle_mole
fonte