Расширение / внедрение кода C # во время компиляции - PullRequest
0 голосов
/ 08 сентября 2018

Я ищу способ расширить / внедрить код во время компиляции, что-то вроде шаблонов / макросов / фрагментов ...

Допустим, я написал этот код во многих местах моего приложения:

[JsonObject("MyProperty")]
private string MyPropertyJson { get; set; }
public object MyProperty { get; set; }

Свойство MyPropertyJson используется только для целей сопоставления EF, поэтому я сохраняю значение в виде строки JSON в БД, но для пользователей класса они знают только о свойстве MyProperty.

Что я хочу сделать, так это то, что во время компиляции MyPropertyJson будет расширен до:

private string MyPropertyJson 
{
    get
    {
        return JsonConvert.SerializeObject(MyProperty);
    }
    set
    {
        MyProperty = JsonConvert.DeserializeObject(value);
    }
}

Я хочу, чтобы это делалось только в выходных двоичных файлах, не затрагивая исходный код.

Я знаю о Unity, PostSharp, Aspect-Injector и т. Д., Но они не достигают того, что я хочу, потому что, используя их, я должен использовать некоторое отражение, чтобы найти и манипулировать MyProperty, но я хочу расширить его точно так же, как он был написан в том же классе с доступом ко всем внутренним компонентам класса.

Это похоже на фрагменты кода, но должно быть расширено на этапе компиляции.

Ответы [ 3 ]

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

Мне удалось выполнить мое требование, написав цель BeforeBuild msbuild для вызова внешнего консольного приложения, которое я разработал для:

  1. Копирование исходных файлов, которые будут перезаписаны во временную папку
  2. Переписать исходный код во временных файлах
  3. Добавлен условный тег Compile в файл .csproj для включения в него манипулированных исходных файлов вместо исходных

Работает как шарм:)

Я работаю над общим движком для этой задачи и передам его на github после завершения.

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

Это способ получить то, что вы хотите.

Использование неявных операторов

Для этого нужно создать собственный класс объектов json, например, затем добавить эти:

class JsonObject {
    public object obj;

    public static implicit operator string(JsonObject target) { 
        return Json.SerializeObject(target.obj);
    }
}

Но это не будет делать то, что вы действительно хотели. Почти так же, как создание нового класса и добавление функций.

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

Решение, которое ничего не стоит и поддерживается в Visual Studio: T4 или Текстовые шаблоны . Однако для этого требуется установить VS SDK (например, 2015 ) и Modeling SDK (например, 2015 ) используемой версии VS.

Для моих библиотек базовых классов я в итоге выделяю сборку для утилит для использования в коде T4, который я пишу в производственном коде. Я использую его в таких местах, как развертывание операций чтения / записи для примитивов в коде ввода-вывода (например, .TT и .CS ). Хотя вам не нужно этого делать, если вам не нужно много / сложного кода времени компиляции gen.

...