У меня есть класс с некоторыми свойствами только для чтения, которые я хочу сохранить с помощью mongodb.
User.cs
public class User: ValueObject<User>
{
public UserId Id { get; }
public string Firstname { get; }
public string Lastname { get; }
public User(UserId id, string firstname, string lastname)
{
Id = new UserId(id.Id);
Firstname = firstname;
Lastname = lastname;
}
public User(string id, string firstname, string lastname)
{
Id = new UserId(id);
Firstname = firstname;
Lastname = lastname;
}
protected override bool MembersEquals(User other)
{
return Id == other.Id && Firstname == other.Firstname && Lastname == other.Lastname;
}
protected override int MembersHashCode()
{
return Id.GetHashCode() ^ Firstname.GetHashCode() ^ Lastname.GetHashCode();
}
}
Регистрация карты классов:
BsonClassMap.RegisterClassMap<User>(cm =>
{
cm.AutoMap();
cm.MapProperty(user => user.Id);
cm.MapProperty(user => user.Firstname);
cm.MapProperty(user => user.Lastname);
cm.MapCreator(user => new User(user.Id, user.Firstname, user.Lastname));
});
этот класс хранится как поддокумент. когда я пытаюсь сохранить весь документ, драйвер mongodb сообщает мне, что MongoDB.Bson.BsonSerializationException: карта создателя для класса Box.Domain.User имеет 3 аргумента, но ни один из них не настроен. . Я не совсем понял, что это значит.
Примечание: класс UserId имеет зарегистрированный сериализатор
public class UserIdBsonSerializer : SerializerBase<UserId>
{
public override UserId Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
var currentBsonType = context.Reader.GetCurrentBsonType();
return currentBsonType switch
{
BsonType.String => new UserId(context.Reader.ReadString()),
_ => throw new NotSupportedException($"Cannot deserialize {currentBsonType} to an UserId")
};
}
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, UserId value)
{
context.Writer.WriteString(value.Id);
}
}
EDIT
ValueObject.cs
public abstract class ValueObject<T> : IEquatable<T>
where T : ValueObject<T>
{
// Verify the value object members equality.
protected abstract bool MembersEquals(T other);
// Generate a hash code depending on the value object members values.
protected abstract int MembersHashCode();
#region Equality
public bool Equals([AllowNull] T other)
{
if (ReferenceEquals(other, null))
return false;
if (ReferenceEquals(this, other))
return true;
return MembersEquals(other);
}
public override bool Equals(object obj)
{
var other = obj as T;
return Equals(other);
}
public static bool operator ==(ValueObject<T> lhs, ValueObject<T> rhs)
{
if (ReferenceEquals(lhs, null) && ReferenceEquals(rhs, null))
return true;
if (ReferenceEquals(lhs, null))
return false;
return lhs.Equals(rhs);
}
public static bool operator !=(ValueObject<T> lhs, ValueObject<T> rhs) => !(lhs == rhs);
#endregion
public override int GetHashCode()
{
return MembersHashCode();
}
}
UserId.cs
public class UserId: ValueObject<UserId>
{
public string Id { get; }
public UserId(string id)
{
if (id.Length < 5)
throw new ArgumentException($"user id must be 5 characters length. {id}");
// TODO: Add more validation rules for user id
Id = id;
}
protected override bool MembersEquals(UserId other)
{
return Id == other.Id;
}
protected override int MembersHashCode()
{
return Id.GetHashCode();
}
}