序列化与 ctor 注入和保护不变量
我可能会在这里遗漏一些明显的东西......
但是当我学会欣赏 IoC 和 ctor 注入的荣耀时,我很难将其与对象图序列化协调起来。这两种模式兼容吗?为什么(或者为什么不)?
假设有:
public class Foo
{
#region invariants
private readonly List<IBar> _bars;
private readonly Guid _id;
#endregion
public Foo( List<IBar> bars, Guid id )
{
_bars = bars.CannotBeNull("bars");
_id = id.CannotBeNull("id");
}
public List<IBar> Bars { get { return _bars; } }
//some other state I want serialized
}
public static class Ex
{
public static T CannotBeNull<T>( this T obj, string paramName = "" )
{
if ( null == obj ) throw new ArgumentNullException(paramName);
return obj;
}
}
我喜欢通过 ctor 注入来保护类不变量的铁定安全。它让我的对象确信他们将永远拥有他们需要的东西。不变量的注入与存储库模式不一致吗?也许有一个 DTO 层和一个工厂模式可以弥补这个差距......?
寻求明智的建议......这两种模式兼容吗?为什么(或者为什么不)?
PS:我知道 IDeserializationCallback 但我不知道它对“私有只读”不变量有什么帮助
I could be missing something obvious here...
But as I learn to appreciate the glory of IoC and ctor injection I am having trouble reconciling this with object graph serialization. Are the two patterns compatible? Why (or why not)?
Suppose there is:
public class Foo
{
#region invariants
private readonly List<IBar> _bars;
private readonly Guid _id;
#endregion
public Foo( List<IBar> bars, Guid id )
{
_bars = bars.CannotBeNull("bars");
_id = id.CannotBeNull("id");
}
public List<IBar> Bars { get { return _bars; } }
//some other state I want serialized
}
public static class Ex
{
public static T CannotBeNull<T>( this T obj, string paramName = "" )
{
if ( null == obj ) throw new ArgumentNullException(paramName);
return obj;
}
}
I like the iron clad saftey of protecting class invariants through ctor injection. It gives my objects the certainty that they will always have what they need. Is injection of invariants at odds with the repository pattern? Maybe there is a DTO layer and a factory pattern somewhere that bridges the gap... ?
Looking for sagely advice... Are the two patterns compatible? Why (or why not)?
PS: I know about IDeserializationCallback but I don't see how it helps with 'private readonly' invariants
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Mark Seemann 有一篇关于该主题的文章,在边界,应用程序不是面向对象的。底线是:在边界应用程序不是面向对象的。如果发生某种翻译(例如序列化),则您的类不变量将无法受到保护。
There is an article by Mark Seemann about that topic, At the Boundaries, Applications are Not Object-Oriented. Bottom line is: at the borders applications are not object oriented. If there is some kind of translation (like serialization) happening, your class invariants can't be protected.
我不清楚你的问题与存储库模式有什么关系。您需要序列化您的存储库吗?
无论如何,使用 XML 序列化都有一个限制,即必须在属性上设置 setter。和你一样,我更喜欢对构造函数保留类不变性,所以我也觉得这很痛苦。这只是在 .Net 中使用 XML 序列化的现实,所以你别无选择(我认为你可以编写自定义序列化程序,但这很痛苦 IIRC)。
如果可以选择,您可能会考虑切换到二进制序列化,它可以序列化私有成员变量。我能找到的最佳来源是这里< /a>.
编辑:我想更直接地回答你的问题:模式本身并不矛盾,但技术实现(使用 XML 序列化时)使它们不兼容。
I'm not clear on what your question has to do with the repository pattern. Do you need to serialize your repository?
In any case, using XML serialization comes with the limitation of having to have setters on your properties. Like you, I prefer to keep class invarients to the constructor, so I find this painful as well. It's simply a reality of using XML serialization in .Net, so you don't have a choice (I think you can write custom serializers, but it's a pain IIRC).
If you have the option, you might look at switching to binary serialization, which can serialize private member variables. Best source I can find is here.
Edit: I guess to answer your question more directly: the patterns themselves are not at odds, but the technology implementation (when using XML Serialization) makes them incompatible.