Преобразование нетипизированной сущности в типизированную (и наоборот)
От: syomin  
Дата: 09.09.15 11:54
Оценка:
Название темы плохо отражает суть моего вопроса, но ничего лучше я не придумал.

Есть сторонняя подсистема, которая оперирует "сущностями". Каждая сущность представляет из себя объект одного и того же класса, имеющего следующие свойства:
  1. Тип сущности — строковое поле, в котором указан тип сущности в терминах предметной области.
  2. Массив элементов типа "имя свойства(string) — значение свойства(string)".

Набор свойств специфичен для каждого типа сущностей. Какие-то свойства могут иметь тип, отличный от строкового (например, DateTime), но в массиве их значение все равно представлено в виде строки.

Количество типов сущностей ограничено и известно на этапе проектирования.

Работать с такими объектами неудобно по очевидным причинам. Хочется сделать на каждый тип сущности свой отдельный класс с типизированным набором свойств и осуществлять преобразование данных на границе подсистем.

Вопрос в том, как с наименьшими затратами реализовать отображение одних сущностей на другие. Посмотрел в сторону Automapper'а, но так и не придумал, как его применить в этих условиях. Может кто подскажет?
Re: Преобразование нетипизированной сущности в типизированную (и наоборот)
От: IB Австрия http://rsdn.ru
Дата: 09.09.15 13:16
Оценка:
Здравствуйте, syomin, Вы писали:

S>Вопрос в том, как с наименьшими затратами реализовать отображение одних сущностей на другие. Посмотрел в сторону Automapper'а, но так и не придумал, как его применить в этих условиях. Может кто подскажет?

Сериализация же... JSON, например, вполне подходит под описанный формат строкового представления сущностей.
Мы уже победили, просто это еще не так заметно...
Re[2]: Преобразование нетипизированной сущности в типизированную (и наоборот)
От: syomin  
Дата: 09.09.15 13:23
Оценка:
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]: Преобразование нетипизированной сущности в типизированную (и наоборот)
От: Sinatr Германия  
Дата: 10.09.15 09:47
Оценка:
Здравствуйте, syomin, Вы писали:

S> А именно, мне нужно, чтобы по имени свойства, взятому из массива, происходило сопоставление со свойством в типизированном объекте.


Тип нигде не указан, откуда брать тип? C известным типом можно было бы просто прогнать Convert.ChangeType по массиву с помощью linq, a без — хз. Можно задать (в определенном порядке) парсинг типов, который выполниться (double.TryParse) раньше — тот и есть нужный.
---
ПроГLамеры объединяйтесь..
Re: Преобразование нетипизированной сущности в типизированную (и наоборот)
От: agat50  
Дата: 10.09.15 09:56
Оценка:
Здравствуйте, syomin, Вы писали:

S>Название темы плохо отражает суть моего вопроса, но ничего лучше я не придумал.


Если хочется "(де)сериализации на лету", надо наверное DynamicProxy какой-нибудь юзать. Есть Linfu, есть Castle. Мб ещё какие-то есть. Если я правильно понял задачу.
Re: Преобразование нетипизированной сущности в типизированную (и наоборот)
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.09.15 13:42
Оценка: 4 (2) +1
Здравствуйте, 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]: Преобразование нетипизированной сущности в типизированную (и наоборот)
От: syomin  
Дата: 10.09.15 14:27
Оценка:
Добрый день!

S>>Работать с такими объектами неудобно по очевидным причинам.

S>А можно раскрыть список этих "очевидных причин"?
S>Какую проблему вы хотите решить?
Вы наверняка работали с ADO.Net, а именно с DataSet'ами. Переход с нетипизированных DataSet'ов на типизированные, а ещё лучше — на любой ORM давал колоссальный выигрыш. Хочется сделать что-то типа этого, но применительно к нашим условиям.

Более того, я сделал свой маппер, который работает через рефлексию и отображает одни сущности в другие. Параметры маппинга задаются с помощью атрибутов.

Я бы хотел применить automapper (или какое-то другое готовое решение), решив при этом ещё одну проблему — по определенным причинам отказаться от разметки атрибутами и перейти на fluent API.

Но тут есть проблема — никак не пойму, как используя automapper построить объект нужного типа (я готов его указать) из коллекции элементов типа "имя свойства" — "значение свойства".
Re: Преобразование нетипизированной сущности в типизированную (и наоборот)
От: MozgC США http://nightcoder.livejournal.com
Дата: 10.09.15 15:06
Оценка: +1
Имхо у вас тут 2 задачи:

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]: Преобразование нетипизированной сущности в типизированную (и наоборот)
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.09.15 05:07
Оценка:
Здравствуйте, syomin, Вы писали:

S>Более того, я сделал свой маппер, который работает через рефлексию и отображает одни сущности в другие. Параметры маппинга задаются с помощью атрибутов.

Отлично. Чем он вас не устраивает?
S>Я бы хотел применить automapper (или какое-то другое готовое решение), решив при этом ещё одну проблему — по определенным причинам отказаться от разметки атрибутами и перейти на fluent API.
Если я правильно понял, автомаппер покрывает исключительно сценарий утиной типизации.
S>Но тут есть проблема — никак не пойму, как используя automapper построить объект нужного типа (я готов его указать) из коллекции элементов типа "имя свойства" — "значение свойства".
По-прежнему непонятно, зачем вам описанное. Поставленная вами задача решается безо всякого автомаппера. Более того — решение у вас уже есть. Что не так?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.