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

в 6:19, , рубрики: .net, .net 4.0, 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 тут, а реализация XDocComparer — тут, прошу пользоваться, если кому-то это может пригодиться.

Автор: kayan

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js