Hướng dẫn mongodb enums - mongodb enums

Tôi đã sử dụng CustomEnumSerializer để xử lý thuộc tính EnumMember

public class CustomEnumSerializer : StructSerializerBase, IRepresentationConfigurable where TEnum : struct
{
    private static readonly Dictionary _fromValueMap = new Dictionary[]; // string representation to Enum value map

    private static readonly Dictionary _toValueMap = new Dictionary[]; // Enum value to string map

    // private fields
    private readonly BsonType _representation;

    // constructors
    /// 
    /// Initializes a new instance of the  class.
    /// 
    public CustomEnumSerializer[]
        : this[[BsonType]0] // 0 means use underlying type
    {
    }

    /// 
    /// Initializes a new instance of the  class.
    /// 
    /// The representation.
    public CustomEnumSerializer[BsonType representation]
    {
        switch [representation]
        {
            case 0:
            case BsonType.Int32:
            case BsonType.Int64:
            case BsonType.String:

                break;

            default:
                var message = string.Format["{0} is not a valid representation for an EnumSerializer.", representation];
                throw new ArgumentException[message];
        }

        // don't know of a way to enforce this at compile time
        var enumTypeInfo = typeof[TEnum].GetTypeInfo[];
        if [!enumTypeInfo.IsEnum]
        {
            var message = string.Format["{0} is not an enum type.", typeof[TEnum].FullName];
            throw new BsonSerializationException[message];
        }

        _representation = representation;

        if [representation == BsonType.String]
        {
            var enumType = typeof[TEnum];
            if [!_fromValueMap.ContainsKey[enumType]]
            {
                Dictionary fromMap = new Dictionary[StringComparer.InvariantCultureIgnoreCase];
                Dictionary toMap = new Dictionary[];

                FieldInfo[] fields = enumType.GetFields[BindingFlags.Static | BindingFlags.Public];

                foreach [FieldInfo field in fields]
                {
                    string name = field.Name;
                    object enumValue = Enum.Parse[enumType, name];

                    // use EnumMember attribute if exists
                    EnumMemberAttribute enumMemberAttrbiute = field.GetCustomAttribute[];

                    if [enumMemberAttrbiute != null]
                    {
                        string enumMemberValue = enumMemberAttrbiute.Value;

                        fromMap[enumMemberValue] = enumValue;
                        toMap[enumValue] = enumMemberValue;
                    }
                    else
                    {
                        toMap[enumValue] = name;
                    }

                    fromMap[name] = enumValue;
                }

                _fromValueMap[enumType] = fromMap;
                _toValueMap[enumType] = toMap;
            }
        }
    }

    // public properties
    /// 
    /// Gets the representation.
    /// 
    /// 
    /// The representation.
    /// 
    public BsonType Representation
    {
        get { return _representation; }
    }

    // public methods
    /// 
    /// Deserializes a value.
    /// 
    /// The deserialization context.
    /// The deserialization args.
    /// A deserialized value.
    public override TEnum Deserialize[BsonDeserializationContext context, BsonDeserializationArgs args]
    {
        var bsonReader = context.Reader;

        var bsonType = bsonReader.GetCurrentBsonType[];
        switch [bsonType]
        {
            case BsonType.Int32: return [TEnum]Enum.ToObject[typeof[TEnum], bsonReader.ReadInt32[]];
            case BsonType.Int64: return [TEnum]Enum.ToObject[typeof[TEnum], bsonReader.ReadInt64[]];
            case BsonType.Double: return [TEnum]Enum.ToObject[typeof[TEnum], [long]bsonReader.ReadDouble[]];
            case BsonType.String:
                var fromValue = FromValue[typeof[TEnum], bsonReader.ReadString[]];
                return [TEnum]Enum.Parse[typeof[TEnum], fromValue.ToString[]];
            default:
                throw CreateCannotDeserializeFromBsonTypeException[bsonType];
        }
    }

    /// 
    /// Serializes a value.
    /// 
    /// The serialization context.
    /// The serialization args.
    /// The object.
    public override void Serialize[BsonSerializationContext context, BsonSerializationArgs args, TEnum value]
    {
        var bsonWriter = context.Writer;

        switch [_representation]
        {
            case 0:
                var underlyingTypeCode = Type.GetTypeCode[Enum.GetUnderlyingType[typeof[TEnum]]];
                if [underlyingTypeCode == TypeCode.Int64 || underlyingTypeCode == TypeCode.UInt64]
                {
                    goto case BsonType.Int64;
                }
                else
                {
                    goto case BsonType.Int32;
                }

            case BsonType.Int32:
                bsonWriter.WriteInt32[Convert.ToInt32[value]];
                break;

            case BsonType.Int64:
                bsonWriter.WriteInt64[Convert.ToInt64[value]];
                break;

            case BsonType.String:
                var val = ToValue[typeof[TEnum], value];
                bsonWriter.WriteString[val];
                break;

            default:
                throw new BsonInternalException["Unexpected EnumRepresentation."];
        }
    }

    private string ToValue[Type enumType, object obj]
    {
        Dictionary map = _toValueMap[enumType];

        return map[obj];
    }
    private object FromValue[Type enumType, string value]
    {
        Dictionary map = _fromValueMap[enumType];

        if [!map.ContainsKey[value]]
            return value;

        return map[value];
    }

    /// 
    /// Returns a serializer that has been reconfigured with the specified representation.
    /// 
    /// The representation.
    /// The reconfigured serializer.
    public CustomEnumSerializer WithRepresentation[BsonType representation]
    {
        if [representation == _representation]
        {
            return this;
        }
        else
        {
            return new CustomEnumSerializer[representation];
        }
    }

    // explicit interface implementations
    IBsonSerializer IRepresentationConfigurable.WithRepresentation[BsonType representation]
    {
        return WithRepresentation[representation];
    }
}

0 hữu ích 0 bình luận chia sẻ 0 bình luận chia sẻ

Chủ Đề