Simple question: I understand that Serialization in C# requires default constructors. This would eliminate the possibility of using Constructor injected DI (which is generally the favored style of DI, in my reading[citation needed]). So is it really an either-or situation, or am I missing something?
(Side question): Do IoC containers side-step this tradeoff somehow?
2 Answers 2
It is not possible to de-serialize an object and also inject a dependency to another, already existing object, in one step in C#, using the standard serialization mechanisms. You will have to use property injection instead, first constructing the object using the deserializer, afterwards injecting the dependency. For most real-world applications, I don't consider this beeing a real drawback - if you have a serializeable data model class, which has also dependencies to other, non-data model classes, you should check if your data model class may have too many responsibilities already.
If that really bothers you, you may consider to wrap your serializable object with a decorator class, where you can pass the de-serializer and additional dependencies through the constructor. That wrapper then executes the two steps (de-serialization of the wrapped object and property injection) in its constructor.
I'm solving this problem like that: injecting factories of dependencies. In those factories, first resolve dependency as it is registered in container, then "deserializing" all remaining data: json.net allows to populate fields in existing object.
As factories code goes along with wiring code of IoC container, I don't think using container.Resolve
inside factory violates the rule, that container
have to be used just in one place in code: where all wiring happens.
As of now, I'm trying to make this process automatic (as opposed to what I've been testing that approach at) using reflection. Yes, there is not much what does remain from json.net deserialization itself, part of it is substituted with custom code, but I think, why bother.
Also, what was your final thoughts/decision on the matter? After reading this post i see two ways: deserialize, then inject; or inject, then deserialize (populate). And i still find my way is better. Will be glad to hear arguments in opposition to this (i'm regarding, that my way may be better for my case, but can't vividly imagine good alternative cases, where it fails, just some minor guesses)
This would eliminate the possibility of using Constructor injected DI
-- Why? You can still have parameterized instructors, so long as you include a default constructor for serialization purposes (the default constructor can be private, if you like).