据我所知,我的类必须具有公共读写属性,以便MongoDB驱动程序对我的对象进行序列化/反序列化。但我想知道是否有方法/首选方法从我的其余代码中隐藏写属性?
例如
class Product
{
private List<Release> releases;
public List<Release> Releases
{
get
{
return new List<Release>(releases); //I can protect 'releases' when reading by passing a copy of it
}
set
{
releases = value; //BUT how can I protect release when writing?
}
}
}
我希望MongoDB能够序列化/反序列化我的类型,但我不希望我的其余代码能够覆盖它本来应该是私有的字段/属性。有处理这个的模式吗?我曾想过有一个单独的ProductDoc
类,它只是用作将对象放入和放出MongoDB的中介,但我不确定是否有更好的解决方案。
答案 0 :(得分:5)
我暂时没有和mongo合作过很长时间。但是你可能会尝试阅读这个帖子MongoDb Map Setters或尝试让你的setter像这样受到保护:
public List<Release> Releases
{
get
{
return new List<Release>(releases); //I can protect 'releases' when reading by passing a copy of it
}
protected set
{
releases = value; //BUT how can I protect release when writing?
}
}
答案 1 :(得分:2)
另一种方法,如果你的属性是由构造函数设置的,那就是让它们保持只读,并使用MapCreator
告诉MongoDB如何创建一个类的实例,传递你想要设置的属性。
e.g。我有一个名为Time
的类,它有三个只读属性:Hour
,Minute
和Second
以及需要一小时,一分钟和第二个值的公共构造函数。
以下是我如何让MongoDB将这三个值存储在数据库中以及在反序列化过程中构造新的Time
对象。
BsonClassMap.RegisterClassMap<Time>(cm =>
{
cm.AutoMap();
cm.MapCreator(p => new Time(p.Hour, p.Minute, p.Second));
cm.MapProperty(p => p.Hour);
cm.MapProperty(p => p.Minute);
cm.MapProperty(p => p.Second);
}
答案 2 :(得分:1)
此页面上的最佳答案目前存在一些很难理解的缺陷。
目前正在编写解决方案:
public List<Release> Releases
{
get
{
return new List<Release>(releases); //I can protect 'releases' when reading by passing a copy of it
}
protected set
{
releases = value; //BUT how can I protect release when writing?
}
}
这不符合书面形式。
obj.Releases.Add(new Release());
会通过向其添加新版本来影响基础集合。这与将设置例程设为私有的既定目标直接矛盾。
但是,如果更改公开的属性类型以实现IEnumerable而不是List并返回列表的ReadOnly版本。比如...
public IEnumerable<Release> Releases
{
get
{
return new List<Release>(releases).AsReadOnly();
}
protected set
{
releases = value;
}
}
然后两个
obj.Releases.Add(new Release());
和
obj.Releases = new List<Release>();
将抛出构建错误并阻止修改底层集合。