序列化是否排除了依赖注入的使用?


9

一个简单的问题:我了解C#中的序列化需要默认构造函数。这将消除使用构造函数注入的DI的可能性(在我的阅读中,通常是DI的首选样式[需要引用])。那么,这真的是一种非此即彼的情况,还是我错过了一些东西?

(附带问题):IoC容器是否以某种方式回避了这种折衷方案?


This would eliminate the possibility of using Constructor injected DI-为什么呢?只要您包括用于序列化目的的默认构造函数(如果愿意,默认构造函数可以是私有的),您仍然可以使用参数化的讲师。
罗伯特·哈维

@RobertHarvey:我感觉有点密集,但是我不太了解你。什么是“参数化讲师”?(typo?)一旦对象被反序列化,我就无法再次构造它。您是否建议我在默认构造的对象上使用属性/设定值注入?
kmote

1
参数化的构造函数是带有参数的构造函数。我在这里假设反序列化发生在从使用依赖注入正确构造的对象派生的数据中。在反序列化过程中,您不必构造对象。它之前已经建造过。
罗伯特·哈维2014年

1
不,您没有记错。这就是它的工作原理。可以将其视为后门注入。您将不会获得任何验证,但是它将起作用。请注意,BinaryFormatter和DataContractSerializer不需要默认的构造函数。
罗伯特·哈维

1
明确地说,所有反序列化操作都是使用XML对象中指定的值填充对象中的状态。它使用反射来完成此操作,并绕过任何形式的构造函数验证逻辑,因此从DI的角度来看,它是作弊的,除非那些XML值最初来自通过普通DI构造的对象。
罗伯特·哈维

Answers:


6

使用标准序列化机制,在C#中的一个步骤中,无法反序列化对象,也不能将依赖项注入到另一个已经存在的对象。您将不得不使用属性注入,首先使用反序列化器构造对象,然后注入依赖项。对于大多数实际应用程序,我不认为这是一个真正的缺点-如果您拥有可序列化的数据模型类,并且该类也依赖于其他非数据模型类,则应检查数据模型类是否具有责任已经太多了。

如果那确实让您感到困扰,则可以考虑使用装饰器类包装可序列化的对象,在其中可以通过构造函数传递反序列化器和其他依赖项。然后,该包装器在其构造函数中执行两个步骤(包装对象的反序列化和属性注入)。


1

我正在解决这样的问题:注入依赖项工厂。在这些工厂中,首先解析在容器中注册的依赖项,然后“反序列化”所有剩余数据:json.net允许填充现有对象中的字段。

当工厂代码与IoC容器的布线代码一起使用时,我认为container.Resolve在工厂内部使用不会违反该规则,该规则container必须在代码中的一个地方使用:所有布线都在其中进行。

到目前为止,我正在尝试使用反射使此过程自动化(与我一直在测试的方法相反)。是的,json.net反序列化本身没有什么剩余,它的一部分被自定义代码替代,但是我认为,为什么要打扰。

另外,您对此事的最终想法/决定是什么?看完这篇文章后,我看到两种方法:反序列化,然后注入;或注入,然后反序列化(填充)。而且我仍然发现自己的方法更好。很高兴听到反对的说法(我认为,我的方法可能对我的情况更好,但无法生动地想象好的替代情况,如果失败,仅需一些小小的猜测)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.