Название темы плохо отражает суть моего вопроса, но ничего лучше я не придумал.
Есть сторонняя подсистема, которая оперирует "сущностями". Каждая сущность представляет из себя объект одного и того же класса, имеющего следующие свойства: Тип сущности — строковое поле, в котором указан тип сущности в терминах предметной области.
Массив элементов типа "имя свойства(string) — значение свойства(string)".
Набор свойств специфичен для каждого типа сущностей. Какие-то свойства могут иметь тип, отличный от строкового (например, DateTime), но в массиве их значение все равно представлено в виде строки.
Количество типов сущностей ограничено и известно на этапе проектирования.
Работать с такими объектами неудобно по очевидным причинам. Хочется сделать на каждый тип сущности свой отдельный класс с типизированным набором свойств и осуществлять преобразование данных на границе подсистем.
Вопрос в том, как с наименьшими затратами реализовать отображение одних сущностей на другие. Посмотрел в сторону Automapper'а, но так и не придумал, как его применить в этих условиях. Может кто подскажет?
Re: Преобразование нетипизированной сущности в типизированную (и наоборот)
Здравствуйте, syomin, Вы писали:
S>Вопрос в том, как с наименьшими затратами реализовать отображение одних сущностей на другие. Посмотрел в сторону Automapper'а, но так и не придумал, как его применить в этих условиях. Может кто подскажет?
Сериализация же... JSON, например, вполне подходит под описанный формат строкового представления сущностей.
Мы уже победили, просто это еще не так заметно...
Re[2]: Преобразование нетипизированной сущности в типизированную (и наоборот)
IB>Сериализация же... JSON, например, вполне подходит под описанный формат строкового представления сущностей
Добрый день! Видимо я не совсем понятно описал задачу. "Сущность" представляет из себя обычный объект вот такого класса:
public class Entity
{
public string EntityType {get; set;}
public Property[] Properties { get; set; }
}
public class Property
{
public string Name {get; set;}
public string Value {get; set;}
}
Т.е. задача (как я её вижу), сводится к тому, чтобы переложить данные из одного объекта в другой. Поэтому я и стал смотреть в сторону Automapper, но с ним возникла проблема — никак не пойму, как с его помощью обработать указанную выше коллекцию свойств. А именно, мне нужно, чтобы по имени свойства, взятому из массива, происходило сопоставление со свойством в типизированном объекте.
Re[3]: Преобразование нетипизированной сущности в типизированную (и наоборот)
Здравствуйте, syomin, Вы писали:
S> А именно, мне нужно, чтобы по имени свойства, взятому из массива, происходило сопоставление со свойством в типизированном объекте.
Тип нигде не указан, откуда брать тип? C известным типом можно было бы просто прогнать Convert.ChangeType по массиву с помощью linq, a без — хз. Можно задать (в определенном порядке) парсинг типов, который выполниться (double.TryParse) раньше — тот и есть нужный.
---
ПроГLамеры объединяйтесь..
Re: Преобразование нетипизированной сущности в типизированную (и наоборот)
Здравствуйте, syomin, Вы писали:
S>Название темы плохо отражает суть моего вопроса, но ничего лучше я не придумал.
Если хочется "(де)сериализации на лету", надо наверное DynamicProxy какой-нибудь юзать. Есть Linfu, есть Castle. Мб ещё какие-то есть. Если я правильно понял задачу.
Re: Преобразование нетипизированной сущности в типизированную (и наоборот)
Здравствуйте, syomin, Вы писали:
S>Работать с такими объектами неудобно по очевидным причинам.
А можно раскрыть список этих "очевидных причин"?
Какую проблему вы хотите решить?
1. Синтаксический оверхед — не хочется писать e.Properties.Single(p=>p.Name=="FirstName").Value, а хочется писать e.FirstName.
2. Статическая верификация кода — хочется, чтобы опечатки типа e.FirtsName на стороне вашего кода отлавливал компилятор, а на стороне кода, с которым вы интегрируетесь — конвертер в "строгую типизацию".
3. Быстродействие вашего кода — у вас много операций доступа к свойствам, и поиск в массиве по имени съедает насолько много времени, что хочется один раз потратить время на перекладывание данных в структуру с константным, а не линейным временем доступа к свойству.
Для первого лучше всего подойдёт custom dynamic object, сконструированный из вашего Entity. Преимущество — не надо описывать никакие типы перед использованием. Один раз описал код доступа — и всё.
Для второго я бы просто написал метод Init(Entity e), который бы пробежался по свойствам текущего объекта при помощи reflection, и за пару десятков строчек получил бы базу для своей системы типов
Для третьего reflection может оказаться слишком медленным, и стоило бы задуматься о хардкоре типа булкита, где маппер генерируется один раз на тип.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Преобразование нетипизированной сущности в типизированную (и наоборот)
Добрый день!
S>>Работать с такими объектами неудобно по очевидным причинам. S>А можно раскрыть список этих "очевидных причин"? S>Какую проблему вы хотите решить?
Вы наверняка работали с ADO.Net, а именно с DataSet'ами. Переход с нетипизированных DataSet'ов на типизированные, а ещё лучше — на любой ORM давал колоссальный выигрыш. Хочется сделать что-то типа этого, но применительно к нашим условиям.
Более того, я сделал свой маппер, который работает через рефлексию и отображает одни сущности в другие. Параметры маппинга задаются с помощью атрибутов.
Я бы хотел применить automapper (или какое-то другое готовое решение), решив при этом ещё одну проблему — по определенным причинам отказаться от разметки атрибутами и перейти на fluent API.
Но тут есть проблема — никак не пойму, как используя automapper построить объект нужного типа (я готов его указать) из коллекции элементов типа "имя свойства" — "значение свойства".
Re: Преобразование нетипизированной сущности в типизированную (и наоборот)
1) Нужен хелпер который будет конвертировать (или пытаться конвертировать) из строки в другой тип данных
2) Удобный интерфейс (класс), который будет конвертировать нетипизированный объект в типизированный.
В итоге это может выглядеть как-то так:
var fields = new List<FieldInfo<MyTypedObject>>
{
Field( 0, o => o.TradeDate), // конвертировать и копировать первое поле в строке в свойство DateTime TradeDate
Field( 1, o => o.TradeDateQuantity), // конвертировать и копировать второе поле в строке в свойство decimal TradeDateQuantity
...
};
var myTypedObjects = mySuperParser.Parse(text, fields);
Re[3]: Преобразование нетипизированной сущности в типизированную (и наоборот)
Здравствуйте, syomin, Вы писали:
S>Более того, я сделал свой маппер, который работает через рефлексию и отображает одни сущности в другие. Параметры маппинга задаются с помощью атрибутов.
Отлично. Чем он вас не устраивает? S>Я бы хотел применить automapper (или какое-то другое готовое решение), решив при этом ещё одну проблему — по определенным причинам отказаться от разметки атрибутами и перейти на fluent API.
Если я правильно понял, автомаппер покрывает исключительно сценарий утиной типизации. S>Но тут есть проблема — никак не пойму, как используя automapper построить объект нужного типа (я готов его указать) из коллекции элементов типа "имя свойства" — "значение свойства".
По-прежнему непонятно, зачем вам описанное. Поставленная вами задача решается безо всякого автомаппера. Более того — решение у вас уже есть. Что не так?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.