Используя атрибуты, чтобы упростить сериализацию класса? - PullRequest
0 голосов
/ 20 сентября 2018

В настоящее время я создаю оболочку для WkHtmlToPdf, чтобы упростить создание консольных переключателей, но я ищу лучший способ сериализации свойств в соответствующие переключатели без необходимости определения метода для каждого отдельного переключателя.Многие из переключателей - простые bools, которые, если они установлены в true, должны быть включены.Есть ли способ использовать атрибуты, которые могли бы упростить сериализацию класса?

Вот упрощенная версия класса свойств:

public class PdfOptions
{
    public bool Book { get; set; }
    public bool Collate { get; set; }
    public Dictionary<string, string> Cookies { get; set; }
    public string CoverUrl { get; set; }
    public Dictionary<string, string> CustomHeaders { get; set; }
    public bool DebugJavascript { get; set; }
    public bool DefaultHeader { get; set; }
    public bool DisableExternalLinks { get; set; }
    public bool DisableInternalLinks { get; set; }
    public bool DisableJavascript { get; set; }
}

Теоретически, я мог бы сделать что-то с атрибутами, чтобы сделать этовыглядит следующим образом:

public class PdfOptions
{
    [WkSwitch(Name = "--book")]
    public bool Book { get; set; }
    [WkSwitch(Name = "--collate")]
    public bool Collate { get; set; }
    [WkCollectionSwitch(Name = "--cookie {key} {value}")]
    public Dictionary<string, string> Cookies { get; set; }
    [WkValueSwitch(Name = "--collate {value}")]
    public string CoverUrl { get; set; }
    [WkCollectionSwitch(Name = "--custom-header {key} {value}")]
    public Dictionary<string, string> CustomHeaders { get; set; }
    [WkSwitch(Name = "--debug-javascript")]
    public bool DebugJavascript { get; set; }
    [WkSwitch(Name = "--default-header")]
    public bool DefaultHeader { get; set; }
    [WkSwitch(Name = "--disable-external-links")]
    public bool DisableExternalLinks { get; set; }
    [WkSwitch(Name = "--disable-internal-links")]
    public bool DisableInternalLinks { get; set; }
    [WkSwitch(Name = "--disable-javascript ")]
    public bool DisableJavascript { get; set; }
}

Но я не совсем уверен, с чего начать, чтобы заставить генераторы генерировать, когда класс сериализован / используется.

1 Ответ

0 голосов
/ 20 сентября 2018

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

var options = new PdfOptions() { ... };
var builder = new StringBuilder();
foreach(var prop in options.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)) {
    var attrs = prop.GetCustomAttributes(typeof(WkAttrBase), false);
    if (attrs.Length != 1) continue; // maybe throw if Length > 1
    switch(attrs[0]) {
    case WkSwitch sw:
        if(prop.GetValue(options) == true) {
            if(builder.Length > 0) builder.Append(" ");
            builder.Append(sw.Name);
        }

Код предполагает, что все атрибуты получены из WkAttrBase и должны быть улучшены с помощью некоторых проверок (например, prop.CanRead и проверки того, что prop.PropertyType - это то, что вы ожидаете).

...