Reputation: 14878
I understand that I must have public read and write properties on my class for MongoDB driver to serialize/deserialize my objects. however I want to know whether there is method/preferred method for hiding the write properties from the rest of my code?
eg.
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?
}
}
}
I want MongoDB to be able to serialize/deserialize my types but I don't want the rest of my code to be able to overwrite it's fields / properties that should otherwise have been private. Is there a pattern to handle this? I have thought about having a separate ProductDoc
class which is just used as a intermediary for getting Product objects into and out of MongoDB, but I'm not sure whether there is a better solution to this.
Upvotes: 5
Views: 5076
Reputation: 39277
Another approach, if your properties are set by the constructor is to keep them read only and to use MapCreator
to tell MongoDB how to create an instance of your class passing in the properties you want to set.
e.g. I have a class called Time
with three readonly properties: Hour
, Minute
and Second
and a public constructor that takes an hour, a minute and a second value.
Here's how I get MongoDB to store those three values in the database and to construct new Time
objects during deserialization.
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);
}
Upvotes: 2
Reputation: 176
The best answer on this page currently has some flaws which are important to understand.
As the solution is currently written:
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?
}
}
This doesn't work as written.
obj.Releases.Add(new Release());
Would affect the underlying collection by adding a new release to it. Which is in direct contradiction to the stated goal of making the set routine private.
However if you change the exposed property type to implement IEnumerable instead of List and return a ReadOnly version of the list. Such as...
public IEnumerable<Release> Releases
{
get
{
return new List<Release>(releases).AsReadOnly();
}
protected set
{
releases = value;
}
}
Then both
obj.Releases.Add(new Release());
and
obj.Releases = new List<Release>();
will both throw build errors and prevent modifying the underlying collection.
Upvotes: 1
Reputation: 5103
I have not worked with mongo for a long time for now. But you may try to read this thread MongoDb Map Setters or try to make your setter protected like this:
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?
}
}
Upvotes: 5