- PVSM.RU - https://www.pvsm.ru -

Использование dynamic для быстрого создания Xml

Не так давно разрабатывал функционал, формирующий по некоторому алгоритму разнообразный xml.
Логично, что при написании первого же теста возник традиционный вопрос ленивого программиста: как сэкономить себе силы, а читающим тесты нервы и быстро и наглядно представить, что же я хочу получить?
Поэтому придумал такой вот способ:

Пример

dynamic rootTag = new XmlBuilder("Root", _nmsps);
dynamic modelTag = new XmlBuilder("Model", _nmsps);
dynamic elementTag = new XmlBuilder("ElementRef", _nmsps);
dynamic attrTag = new XmlBuilder("ElementAttribute", _nmsps);

 XDocument doc =
                rootTag(id: Guid.Empty,
                model: modelTag(id: model.ObjectId, name: model.Name,
                                     e1: elementTag(id: er.ObjectId, name: elem1.Name, 
                                           ea1: attrTag(id: attr1.ObjectId, name: attr1.Name),
                                           ea2: attrTag(id: attr2.ObjectId, name: attr2.Name)),
                                     e2: elementTag(id: er2.ObjectId, name: elem2.Name)));

XmlBuilder — самописный класс, наследующийся от DynamicObject.
Для создания документа он вызывается как метод и преобразует аргументы либо в атрибуты на основании имени параметра — если это аргумент любого типа, кроме XmlBuilder — либо в дочерние элементы (тут имя параметра не важно) — если это XmlBuilder.
При этом каждый XmlBuilder представляет некоторый тэг в результирующем документе.

В тесте сравниваем то, что надо с тем, что получилось, используя несложный компаратор, в итоге этот тест выглядит как-то так:


//формируем входные данные для теста
//...


//формируем документ, которому должен соответствовать результат
dynamic rootTag = new XmlBuilder("Root", _nmsps);
dynamic modelTag = new XmlBuilder("Model", _nmsps);
dynamic elementTag = new XmlBuilder("ElementRef", _nmsps);
dynamic attrTag = new XmlBuilder("ElementAttribute", _nmsps);

 XDocument targetDocument =
                rootTag(id: Guid.Empty,
                model: modelTag(id: model.ObjectId, name: model.Name,
                                     e1: elementTag(id: er.ObjectId, name: elem1.Name, 
                                           ea1: attrTag(id: attr1.ObjectId, name: attr1.Name),
                                           ea2: attrTag(id: attr2.ObjectId, name: attr2.Name)),
                                     e2: elementTag(id: er2.ObjectId, name: elem2.Name)));

//выполняем
var resultDocument = TestableMethod();
//проверяем
var _comparer = new XDocComparer();
Assert.IsTrue(_comparer.Equals(targetDocument, resultDocument));

Для простоты пришлось пожертововать ненужными для меня возможностями (декларациями, например).
Ну и компаратор, в силу того, что он есть IEqualityComparer, не показывает что именно не совпадает, а только конечный результат.

Тем не менее, реализация XmlBuilder тут [1], а реализация XDocComparer — тут [2], прошу пользоваться, если кому-то это может пригодиться.

Автор: kayan

Источник [3]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/net/30953

Ссылки в тексте:

[1] тут: http://pastebin.com/MvTurW6e

[2] тут: http://pastebin.com/mHXbNMPW

[3] Источник: http://habrahabr.ru/post/175051/