Страницы

Поиск по вопросам

Показаны сообщения с ярлыком кодогенераторы. Показать все сообщения
Показаны сообщения с ярлыком кодогенераторы. Показать все сообщения

пятница, 27 декабря 2019 г.

Какие инструменты для генерации кода вы используете в своих .Net проектах?

#c_sharp #net #кодогенераторы


Не редко, при разработке крупных и сложных приложений приходится заниматься написанием
большого количества однотипного простого кода, например при описание DTO и кода, который
их сериализует/десериализует. Процесс этот может быть несильно увлекательным и интересным,
и может приводить к ошибкам. Для решения этой и не только задачи, весьма успешно можно
применять инструменты для автоматической генерации кода.

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


Ответы

Ответ 1



Генерацию модели (я предпочитаю бескровную) оставляю за собой (пишу рукми), доступ к БД (опыт пока только с реляционными MS SQL && Postgre SQL) Dapper && EF6+, Dto тоже пилю руками, сериализация/десериализация, там все просто, в зависимости от требования XmlSerializer (забыл уже, когда последний раз использовал)/Json .Net/ BinarySerializer/под кастомные форматы использую рефлексию и MindboxExpressions (см. Nuget), маппинг модели на дто и обратно - AutoMapper (все задается через конфигурацию), валидация = FluentValidation .Net. Ах да, совсем забыл, для логирования/трассировки NLog, IoC = (Ninject|Autofac)

воскресенье, 15 декабря 2019 г.

Генерация кода (Java/C#). Поделитесь опытом.

#кодогенераторы #java #c_sharp


Возникла необходимость использовать генератор кода. Предположительно нужно будет
генерировать код на Java и/или C#. Генерировать хотелось бы на основе UML-диаграмм
+ каких-то шаблонов на простом языке. Обнаружилось довольно-таки много различных генераторов,
которые в том или ином объеме решают задачу. Чтобы было понятнее, о чем речь, в качестве
примера можете посмотреть генератор Agile Platform. Прошу тех, кто использовал подобные
генераторы, поделиться впечатлениями. Предлагаю такой формат:

Название генератора.
Удобство в использовании.
Экономия времени (по сравнению с написанием кода вручную).
Расширяемость (интересует в первую очередь, можно ли генерировать код на своих языках
путем описания их синтаксиса).
Краткое описание впечатлений (в двух словах!).

Большая просьба не превращать в обсуждения типа "генерация кода: хорошо это или плохо?".
Интересует мнение тех, кто использовал генераторы на практике или хотя бы в свое время
с ними ознакомился. Спасибо.    


Ответы

Ответ 1



У нас есть кодоген из java классов в c++ и c# + второй кодоген джавы по джаве. Основные мысли Писать только самому, потому что саппорта и маленьких "рюшечек" кодоген требует немало. Если у вас зоопарк языков и сред - кодогенить лучше всего на основе стороннего описателя, например xml файлика. Через 3 дня у вас конечно всё заработает в основном... Но ещё 3 недели надо будет потратить чтобы покрыть все исключения :) Кодоген это добро! И чем больше проект тем большее это добро. На одном из прошлых проектов кодоген у нас появился когда нас было всего трое и кода было не больше 30к строк. Уже тогда он помогал здорово. Ну и правила написанные кровью: КОДОГЕН ДОЛЖЕН БЫТЬ ДЕТЕРМЕНИРОВАННЫМ. По одинаковым файлам результат должен быть одинаков до байта. КОДОГЕН ДОЛЖЕН БЫТЬ ПОКРЫТ ТЕСТАМИ НА 100%.

Ответ 2



Кодогенератор у нас свой (только не по UML, а по схеме БД). Если на заморачиваться с CodeDOM (чтобы сделать генератор независимым от языка программирования), пишется довольно быстро. Тупой генератор кода по схеме БД пишется где-то полдня. Навороченный, с возможностью тонкой настройки маппинга (наследование, енумы, пространства имён с разными префиксами, переопределение свойств физических объектов БД) - дня три.

Ответ 3



Где-то лет десять назад я принимал участие в создании подобного генератора. Суть задачи была такая: есть UML диаграмма теста шины процессора согласно спецификации, и нужно, путем ряда преобразований, превратить ее в код на языках описания аппаратуры (VHDL, Verilog, SystemC и т.п.). Делалось это с помощью Yacc/Bison и XSLT силами нескольких студентов-интернов в течение месяца. Резюме. Написать генератор оказалось несложно и практическая польза была значительной, но сама поддержка в дальнейшем (когда студенты ушли по другим проектам) была хлопотной; поэтому если есть возможность купить готовый, лучше купить готовый. Польза генератора проявлялась тогда, когда нужно было генерировать сразу в несколько языков, если же требовался тест на одном языке, то особого преимущества перед написанием кода не чувствовалось.

Ответ 4



Вот простой и неприхотливый инструмент для генерирования UML кода и построения диаграмм классов из java кода: java2uml.

суббота, 6 июля 2019 г.

Компилирование и повторная загрузка сборки в runtime

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

Положим, есть такой интерфейс:
namespace MyAppNamespace { public interface INamed { string Name { get; } } }
Далее внутри приложения генерируется следующий код (и кладется в resultCode):
using MyAppNamespace;
public class Wrapper : INamed { public string Name { get { return "Test"; } } }
Компилирую это дело:
// Указываю, что на выходе мне не нужен исполняемый файл, а также что сборку нужно создать по указанному пути CompilerParameters options = new CompilerParameters { GenerateExecutable = false, GenerateInMemory = false, OutputAssembly = $"{SavePath}.dll" }; options.ReferencedAssemblies.Add(new Uri(GetType().Assembly.CodeBase, UriKind.Absolute).LocalPath); // Добавляю ссылку на текущую сборку для наследования интерфейса // Получаю результат компиляции CompilerResults results = new Microsoft.CSharp.CSharpCodeProvider().CompileAssemblyFromSource(options, resultCode); // Опустим проверки // Загружаю сборку из массива байт (так как сам файл потом, возможно, может быть удален) Assembly asm = Assembly.Load(File.ReadAllBytes(results.PathToAssembly)); // Создаю instance типа, который в сборке унаследован от нужного интерфейса INamed named = (INamed)Activator.CreateInstance(asm.DefinedTypes.First(x => x.ImplementedInterfaces.Contains(typeof(INamed))).AsType()); asm = null; GC.Collect(); // Вычищаю сборку из памяти. По крайней мере, я хочу в это верить return named;
После этого я могу спокойно получать доступ к named.Name. Через некоторое время объект "выбрасывается", пока пользователь явно не укажет, что хочет его использовать. В таком случае его нужно будет повторно достать из сборки
Но есть одно жирное но: если я попытаюсь тем же самым образом загрузить сборку и достать из нее тип во второй раз, то визуально процесс пройдет успешно, но при попытке доступа к named.Name вылетит ошибка, что сборка, в которой он определен, не найдена

Я могу поправить логику приложения и сделать считывание единоразовым (пожалуй, это будет даже правильнее), но сейчас для меня важно понимание, почему же так происходит: при первом считывании все работает как часы, а при втором считывании тем же самым способом из того же самого файла процесс проходит успешно, но объект оказывается "битым", так как при попытке доступа к его свойствам я получу ошибку о том, что сборка не может быть загружена


Ответ

Вычищаю сборку из памяти. По крайней мере, я хочу в это верить
Увы, эта вера не имеет оснований. Использованный вами способ загрузки сборки не только не позволяет выгрузить сборку из памяти без выгрузки всего домена приложений, но и при каждом повторном запуске будет грузить сборку с того же пути заново (иными словами, это хороший способ исчерпать память при длительной работе программы).
Создайте Dictionary (где string будет путем к файлу) и кэшируйте все загружаемые сборки в нем. Можно использовать вместо пути CRC/хэш файла, если вам нужно как-то учесть само содержимое файла. Или грузить каждую сборку в новый домен приложений, тогда их можно будет выгрузить (вообще, это обычная практика при создании приложений с расширениями).