Обновление
Вот еще некоторая информация о бизнес-логике моего приложения, основанная на замечании @ aman о том, что "может иметь возможность извлечь те элементы из словаря, от которых зависит ваш бизнес-код, и представить их в виде их лунки свойства ".
Соответствующей частью заявки является реестр (финансовых) продуктов. Приложение позволяет опытным пользователям определять дополнительные поля в продуктах, а также определять ограниченную бизнес-логику. Например. они могут определить поле с именем RiskValue
типа decimal
и RiskColor
типа string
и часть бизнес-логики, которая может сказать
Если RiskColor больше 1,5, тогда RiskColor должен быть красного цвета
Теперь эта бизнес-логика должна иметь возможность привести RiskColor
к decimal
, чтобы выполнить сравнение, и именно здесь возникает проблема.
На основании приведенных выше определений можно было бы создать класс во время выполнения, что-то вроде:
public class Product
{
public decimal RiskValue { get; set; }
public string RiskColor { get; set; }
public void BusinessLogic( )
{
if( RiskValue > 1.5M)
RiskColor = "Red";
}
Но я не уверен, что хочу пойти по этому пути.
У меня есть некоторые классы моделей (в C #), где некоторые свойства не известны во время компиляции. Итак, у меня есть
[BsonExtraElements]
IDictionary<string,object> ExtraElements {get;}
(на самом деле BsonExtraElements заключает соглашение, но я не думаю, что это имеет значение).
Некоторые из этих свойств имеют тип System.Decimal
, например.
obj.ExtraElements["PropertyX"] = 1.000M;
Когда я сохраняю объект в MongoDB, он сериализуется следующим образом:
{
...
"PropertyX" : NumberDecimal("1.000"),
}
что я и ожидаю.
Однако, когда я считываю объект обратно в мою модель, значение свойства имеет тип MongoDB.Bson.Decimal128
вместо ожидаемого System.Decimal
.
Большая часть приложения (за исключением уровня данных) не зависит от основного механизма хранения, поэтому я также регистрирую [BsonExtraElements]
с помощью соглашения, а не с помощью атрибута (сборка, содержащая мою модель, не имеет ссылка на драйвер MongoDB). Я ищу решение, где мне не нужно засорять мой код специфическим кодом MongoDB. Я надеюсь, что есть флаг, который я пропустил, или, возможно, какой-то способ создать пользовательское соглашение, чтобы исправить его на уровне драйвера.
На данный момент я решил эту проблему, реализовав IDictionary<string,object>
в классе с именем ExtraElementsDictionary
и передав значение через этот метод для каждого действия:
private static object FixValue( object value )
{
if( value == null ) return null;
if( value.GetType( ).FullName == "MongoDB.Bson.Decimal128" )
{
return decimal.TryParse( value.ToString( ), out var dec ) ? dec : default;
}
return value;
}
Я также подумал сделать это на уровне данных, что-то вроде
public MyModel GetMyModelById(string id)
{
// actual retrieval of object
FixDecimal128(obj.ExtraElements);
return obj;
}
Но должен быть лучший способ?