Как создать приложение на с
Перейти к содержимому

Как создать приложение на с

  • автор:

 

Разработка кроссплатформенных модульных приложений на C++ с библиотекой wxWidgets

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

И вот, есть возможность сейчас рассказать о наработках, которые появились за последнее время. Надеюсь, кому-то этот текст сильно упростит жизнь и даст толчок к покорению новых вершин.

В этот раз речь пойдет о создании кроссплатформенных приложений с плагинами на C++ с использованием библиотеки wxWidgets. Рассматриваться будут операционные системы Windows, Linux и OS X, как наиболее популярные.

Как обычно, первая часть будет обзорной, для того, чтобы снизить порог входа для читателей. Кому-то информация из первой части покажется очевидной (особенно то, что касается инструментария), но, все же, я считаю ее необходимой, ибо для новичков информация из первой части позволит с минимальными усилиями организовать процесс разработки.
Дальше — поэтапный разбор кода тестового приложения с пояснениями.

Инструментарий

wxWidgets

Для начала нам понадобятся:

Библиотека wxWidgets в исходных кодах. Я использую наиболее новые версии из SVN. Они, конечно, не без багов, зато в них реализован функционал, которого обычно не хватает в официальных релизах.

Более подробно о процессе сборки библиотеки можно почитать здесь: http://habrahabr.ru/post/123588/

Разница в процессе сборки, по сравнению с указанной выше статьей заключается лишь в том, что нужно использовать конфигурацию DLL Debug и DLL Release вместо Debug и Release . К тому же, обязательно необходимо чтобы в настройках всех проектов, входящих в дистрибутив wxWidgets, в параметре C/C++ -> Code Generation -> Runtime Library были указаны значения Multi-Threaded Debug DLL и Multi-Threaded DLL . Именно с «DLL» в конце. В этом случае у нас wxWidgets будет собрана в виде динамических библиотек и с динамическим CRT.

При сборке конфигураций DLL Debug и DLL Release может быть такое что не все библиотеки соберутся с первого раза. Все это из-за проблем с указанием зависимостей. Если не собралось, запускаем сборку еще раз. Обычно 2-3 итераций достаточно для того, чтоб получить полный комплект динамических библиотек.

Напомню также, что для работы с wxWidgets необходимо наличие переменной окружения %WXWIN% (для Windows), которая указывает на папку с исходными кодами wxWidgets. Для Linux и OS X достаточно выполнить configure && make && make install .

  • Debug: configure —enable-shared —disable-static —enable-unicode —disable-compat28 —disable-final —enable-debug
  • Release: configure —enable-shared —disable-static —enable-unicode —disable-compat28 —enable-final —disable-debug
CMake
  • /usr/local/bin/wx-config
  • /usr/local/bin/wxrc

Также надо иметь в виду тот факт, что если вы установили Debug-версию wxWidgets, то в Linux и OS X у вас, скорее всего, получится собрать только Debug-версию приложения. Это же касается и Release-версии. А все потому что CMake берет параметры компиляции и линковки из скрипта wx-config, который по умолчанию отдает параметры для одной текущей конфигурации. Или для Debug отдельно, или отдельно для Release.

Visual C++ (Windows)

Для сборки wxWidgets и нашего приложения из исходных кодов в Windows будем использовать Visual C++ 2012. Express редакция тоже подойдет. Это значит, что все средства разработки, включая IDE и компилятор, будут бесплатными.

DialogBlocks

Для создания интерфейса пользователя, дабы не писать все руками, рекомендую использовать приложение DialogBlocks. Таки-да, он платный, но есть бесплатная пробная версия, которой достаточно для создания несложных форм. Хотя опять же, никто не мешает писать все руками (кстати, это даже неплохо в воспитательных целях и явно положительно сказывается на понимании кода).

Начало

Структура папок
  • build – папка с общим CMake скриптом и shell-скриптами для генерирования проектов
  • build/bin/<Configuration> — папка, куда компилятор складывает бинарные файлы
  • /include – папка с общими заголовками (например, для precompiled headers)
  • /<ProjectName> — папка с исходными кодами проекта из главного решения (может быть более одного проекта в решении, у каждого своя папка)
  • /<ThirdParty> — папка, в которой лежат сторонние библиотеки (в виде исходников или собранные, каждая в своем подкаталоге)
  • /ThirdParty/build – папка с общим CMake скриптом и shell-скриптами для генерирования проектов сторонних библиотек (если вы решите вынести их в отдельный solution)
  • /ThirdParty/<LibName> — папка с исходными кодами сторонней библиотеки (их может быть более одной)
  • /<ProjectName>/<OS-Name> — сюда CMake складывает файлы проектов для каждой ОС.
Главный CMakeList

Главный скрипт CMake содержит общие параметры и настройки для всех проектов, а также описание некоторых общих переменных.

build/CMakeLists.txt

Скрипты для генерирования проектов

Для простоты использования CMake лучше использовать shell- или batch-скрипты. Это позволит немного сэкономить время на рутинных операциях типа вызова CMake и настройки переменных окружения.

Windows (cm.bat)

Для удобства, лучше использовать раздельные batch-скрипты для создания проектов Visual Studio для x86 и x64, а также один общий скрипт, который будет определять, под какую платформу собираем приложение:

Windows (cm86.bat)
Windows (cm64.bat)
Linux (cmLinux.sh)

Минимальное wxWidgets-приложение с CMake

Для начала работы нам нужен шаблон приложения, в который мы будем добавлять функционал. Создадим простое приложение, состоящее из класса приложения (например wxModularHostApp) и класса главной формы (например MainFrame).

Если использовать DialogBlocks, то, помимо пары файлов h/cpp для каждого класса, получим еще .rc файл с описанием ресурсов приложения.

Код приводить не буду. Пример можно взять из прошлых статей или из папки %WXWIN%\samples\minimal

Теперь можно переходить к созданию CMake-скрипта.

wxModularHost/CMakeLists.txt

Предварительно откомпилированные заголовки (Precompiled Headers)

Для ускорения процесса компиляции, есть возможность использовать предварительно откомпилированные заголовки (http://en.wikipedia.org/wiki/Precompiled_header).

Для реализации этой возможности нам понадобятся два файла:
include/stdwx.h

include/stdwx.cpp

Помимо файлов с исходным кодом C++ нам надо еще научить CMake добавлять в проект Visual Studio нужные правила для работы с предварительно откомпилированными заголовками. Для этого нам поможет специальный модуль. Не припомню, откуда он взялся, но вроде отсюда (http://public.kitware.com/Bug/file_download.php?file_id=901&type=bug). Исходный код CMake-модуля для поддержки предварительно компилируемых заголовков можно посмотреть здесь: https://github.com/T-Rex/wxModularApp/blob/master/build/PCHSupport.cmake.

Этот модуль надо включить в build/CmakeLists.txt таким образом:

build/CMakeLists.txt

После подключения предварительно откомпилированных заголовков в проект, первой строкой во всех .CPP файлах проекта должна быть строка

Простейший плагин без GUI

Библиотека с базовыми классами

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

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

wxNonGuiPluginBase/Declarations.h

wxNonGuiPluginBase/wxNonGuiPluginBase.h

Файл Declarations.h содержит определение макроса DEMO_API , который указывает, экспортируемый у нас класс wxNonGuiPluginBase или импортируемый. Делается это с помощью атрибутов dllexport/dllimport (см. http://msdn.microsoft.com/en-us/library/3y1sfaz2(v=vs.90).aspx) в зависимости от наличия директивы препроцессора DEMO_PLUGIN_EXPORTS . При сборке библиотеки wxNonGuiPluginBase мы указываем DEMO_PLUGIN_EXPORTS в списке директив препроцессора, а при сборке плагинов, зависящих от библиотеки wxNonGuiPluginBase и при сборке основного приложения – не указываем. Таким образом для проекта wxNonGuiPluginBase значение DEMO_API будет содержать атрибут dllexport , а для всех остальных проектов – значение dllimport .

wxNonGuiPluginBase/wxNonGuiPluginBase.cpp

wxNonGuiPluginBase/CMakeLists.txt

Как было сказано ранее, макрос PREPROCESSOR_DEFINITIONS содержит декларацию макроса DEMO_PLUGIN_EXPORTS , который используется в файле Definitions.h

Первый плагин

В плагине нам надо сделать класс, производный от wxNonGuiPluginBase , реализовать в нем рабочий функционал, а также сделать экспортируемые функции для создания экземпляра класса и для его удаления. Эти функции будут вызываться основным приложением.

SampleNonGuiPlugin/SampleNonGuiPlugin.h

SampleNonGuiPlugin/SampleNonGuiPlugin.cpp

SampleNonGuiPlugin/SampleNonGuiPlugin.def

SampleNonGuiPlugin/SampleNonGuiPluginExports.cpp

SampleNonGuiPlugin/CMakeLists.txt

Модуль управления плагинами

Итак, на данный момент у нас есть хост-приложение и минимальный плагин. Теперь надо реализовать загрузку и использование плагина в приложении. В целях универсальности, лучше выделить код, который будет заниматься поиском, загрузкой и выгрузкой плагинов из памяти, в отдельный класс, а еще лучше – в отдельную библиотеку.

  • Плагин – это динамическая библиотека
  • В библиотеке есть экспортируемые функции CreatePlugin() и DeletePlugin()
  • Весь функционал плагина реализуется в соответствующем классе внутри динамической библиотеки, объект этого класса возвращается функцией CreatePlugin()
  • Класс внутри библиотеки реализует публичный интерфейс wxNonGuiPluginBase , о котором знает и приложение.
  • Библиотека должна быть загружена в память на протяжении всего времени жизни объект, который приложение получает из функции CreatePlugin()
  • По завершении работы с плагином нам необходимо удалить объект из памяти (это делает функция DeletePlugin() ) и выгрузить из памяти библиотеку.
  • Помимо загрузки и выгрузки данных из памяти, приложение должно еще уметь находить однотипные плагины в специально предназначенной для этого папке.
  • Раз плагинов может быть более одного, то надо хранить список загруженных библиотек в памяти
  • Раз библиотек может быть более одной, то надо хранить список загруженных из библиотек объектов в памяти
  • Раз библиотека должна быть выгружена из памяти не ранее, чем удалится соответствующий рабочий объект, надо как-то обеспечить возможность отлеживать соответствия библиотеки этому объекту.
  • В заголовочном файле есть декларация списка загруженных библиотек ( wxDynamicLibraryList ), списка загруженных из библиотеки объектов-плагинов ( wxNonGuiPluginBaseList ), а также хеш-таблицы, которая позволяет отследить соответствие библиотеки плагину ( wxNonGuiPluginToDllDictionary )
  • Класс управления плагинами содержит метод, который возвращает путь к папке, в которой приложение будет искать плагины, а также метод, который возвращает расширение файлов плагинов (по умолчанию для Windows это .dll, а для Linux и OS X это .so)
  • Также класс содержит список библиотек, список объектов-плагинов и таблицу соответствий плагинов библиотекам.
  • Есть методы загрузки и выгрузки библиотек из памяти.
  • В классе есть поле m_Settings . Это указатель на объект, который будет хранить настройки системы (например, флаг, который определяет, где искать плагины и, возможно, данные или конфигурационные файлы для них, в папке с программой или в специальной папке настроек, путь к которой определяется системой). Более подробно класс настроек мы рассмотрим далее.

Есть смысл обратить внимание на метод LoadNonGuiPlugins() , в котором с помощью макроса wxDYNLIB_FUNCTION мы получаем указатель на функцию CreatePlugin() . Тип указателя CreatePlugin_function определен в wxNonGuiPluginBase.h.

Также есть смысл обратить внимание на метод UnRegisterNonGuiPlugin() , в котором происходит поиск плагина в таблице соответствий, если плагин найден то для него из найденной библиотеки вызывается функция DeletePlugin() и библиотека выгружается. Если плагин не найден в таблице (например, он реализован в приложении и мы его добавляли в список вручную), то он просто удаляется из памяти.

wxModularCore/wxModularCoreSettings.h

wxModularCore/wxModularCoreSettings.cpp

wxModularCore/CMakeLists.txt

И еще надо не забыть включить путь к проекту wxModularCore в основной CMakeLists.txt:

build/CMakeLists.txt

Использование плагинов без GUI в приложении

Раз класс, управляющий плагинами, у нас уже готов, то можно начать им пользоваться в приложении.

Для начала поле-указатель на wxModularCore в класс приложения:

wxModularHost/wxModularHostApp.h

wxModularHost/wxModularHostApp.cpp

И вот таким образом мы будем вызывать метод загрузки плагинов и пользоваться самими плагинами:

wxModularHost/wxModularHostApp.cpp

В методе TestNonGuiPlugins() мы сначала вызываем метод LoadPlugins() из wxModularCore , если он отработал корректно, то проходимся по списку плагинов и для каждого элемента списка вызываем метод Work() (напомню, он задекларирован в проекте wxNonGuiPluginBase, а фактически имеет разную реализацию для каждой из загруженных библиотек).

Простейший GUI-плагин

Как создавать модули, содержащие только логику, разобрались. Теперь рассмотрим пример модуля, который кмеет создавать окно:

wxGuiPluginBase/wxGuiPluginBase.h

  • GetName() – возвращает название модуля
  • GetId() – возвращает уникальный идентификатор модуля (можно использовать GUID для этого, в Visual Studio для этих целей есть специальная утилита. См. меню Tools -> Create GUID )
  • CreatePanel() – создает элемент управления (для демонстрации нас устроит любой контрол) и возвращает указатель на него.

SampleGuiPlugin1/SampleGuiPlugin1.h

SampleGuiPlugin1/SampleGuiPlugin1.cpp

CMakeLists.txt для этого плагина почти аналогичен тому, который мы написали для плагина без GUI. Отличия будут только в названии проекта и в списке входящих в проект файлов.

Рефакторинг модуля управления плагинами

На данный момент у нас есть два типа плагинов. Для плагинов без GUI в классе управления плагинами есть специализированный метод для загрузки библиотек, регистрации плагинов, отключения плагинов. С таким подходом нам нужно будет дублировать все эти методы для каждого типа плагинов. И есть таковых у нас будет 5-10, то класс неоправданно разрастется в размерах. Поэтому методы LoadXXXPlugins() , UnloadXXXPlugins() , RegisterXXXPlugin() , UnRegisterXXXPlugin() было решено сделать шаблонными, списки и хеш-таблицы вынести в отдельный класс-наследник класса wxModularCore , который будет содержать код, специфичный для нашего приложения.
wxModularCore/wxModularCore.h

wxModularHost/SampleModularCore.h

wxModularHost/SampleModularCore.cpp

После реализации шаблонных методов, добавление поддержки GUI-плагинов заняло совсем немного кода.

Использование GUI-плагинов в приложении

В приложении у нас есть главная форма с менеджером Docking-окон и wxAuiNotebook в качестве центральной панели. Рассмотрим как можно добавить контролы из плагинов в этот wxAuiNotebook:
wxModularHost/MainFrame.cpp

В результате получим такое окно с вкладками:

image

Заголовки вкладок берутся из метода GetName() каждого плагина, сами же вкладки создаются методом CreatePanel() плагина.

Доработки CMake-скриптов для Linux

В Windows для указания папки, в которую будут собираться динамические библиотеки, мы указывали с помощью настройки RUNTIME_OUTPUT_DIRECTORY . В Linux, т.к. плагин – это динамическая библиотека (именно библиотека), используется настройка LIBRARY_OUTPUT_DIRECTORY . Но здесь мы сталкиваемся с проблемой: если собирать библиотеки прямо внутрь папки bin, то линкер не будет находить эту библиотеку при сборке зависимых проектов. Для этих целей нужно добавить скрипт, который будет отрабатывать после сборки библиотеки и копировать ее в нужное место внутрь папки bin. Сделать это нужно будет для всех динамических библиотек (и для базовых и для плагинов):

SampleGuiPlugin2/CMakeLists.txt

Для всех плагинов в Linux мы также должны указать список зависимостей:

SampleGuiPlugin2/CMakeLists.txt

Вроде все хорошо, проект собирается. Но при попытке запустить приложение мы обнаружим что динамические библиотеки не загружаются (это может стать неприятной неожиданностью в случае переноса на другую машину уже собранного приложения).
А все потому, что при сборке внутрь библиотеки прописываются ссылки на зависимости с полными путями. Так, например, для каждого плагина будет указан полный путь к библиотеке с базовыми классами, которой на другой рабочей машине не будет. Проверить это можно с помощью утилиты ldd:

Для того, чтобы избавиться от полных путей, в CMake надо указать опцию RPATH для библиотек, которые ссылаются на другие динамические библиотеки из нашего решения:

Создание первого приложения на C++

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

Ниже мы создадим первую утилиту на языке C++. Он выбран как самый распространенный «метод создания программ». Широко применяется на практике и дает возможности создания игр, бизнес-решений, офисных утилит, а также виджетов для различных устройств. Главное – знать синтаксис и ключевые функции.

Термины

Перед тем, как писать первую программу на C, необходимо сначала запомнить ключевые понятия в программировании. Они пригодятся всем, кто изучает объектно-ориентированную парадигму.

Пока пользователь не запомнит следующие определения, писать код не имеет никакого смысла:

  1. Алгоритмы – правила и принципы, которые помогают решать поставленную перед программистом задачу.
  2. Программа – организованный набор инструкций, который при выполнении реализовывает функции.
  3. API – интерфейс прикладного программирования. Протоколы, процедуры и правила, необходимые для создания ПО. Помогают утилитам взаимодействовать с различными службами и софтом.
  4. Аргументы – значения, которые передаются в команды и имеющиеся функции.
  5. Булево – выражение, необходимое для операторов, работающих со значениями True и False.
  6. Символ – элементарная единица отображения информации.
  7. Объект – связанные переменные, константы, структурные единицы, которые могут совместно выбираться и проходить последующую обработку.
  8. Классы – наборы связанных объектов. У них есть общие свойства/параметры.
  9. Код – письменный набор инструкций, составленный на заданном ЯП с учетом имеющихся протоколов.
  10. Компиляция – создание исполняемой программы.
  11. Константа – значение, которое не будет меняться по ходу работы утилиты.
  12. Массив – сгруппированные списки или множества типов значений данных.
  13. Фреймворк – готовый набор блоков кода. Используется для ускорения разработки.
  14. Итерации – проходы через заданные наборы операций в приложении.
  15. Переменные – зарезервированные ячейки памяти. Основные компоненты, с которыми предстоит работать программисту.
  16. Ключевые слова – слова, зарезервированные ЯП для обозначения команд, функций и операций.
  17. Операнд – объект, которым удается управлять в первой программе на C (и последующем софте) через операторы.
  18. Оператор – объект, умеющий манипулировать операторами.
  19. Пакет – организованный модуль связанных между собой интерфейсов и классов.

Начало изучения процедуры написание первых утилит необходимо не только с «базовой» терминологии. Также стоит обратить внимание на то, как организовать работу. Программисту предстоит выбрать среду разработки, изучить соответствующий инструментарий. Синтаксис выбранного ЯП можно рассматривать постепенно.

Что нужно на первых порах

Начало написания первой программы будет происходить на примере Windows. Для успешного старта пользователю предстоит установить некоторые инструменты. А именно:

  • Visual Studio;
  • Dec C++ 5 версии;
  • GCC компилятор – для тех, кто работает в системах типа Unix.

А еще клиенту необходимо обеспечить наличие любого текстового редактора. Пример – Vim. Без него первую утилиту создать окажется весьма проблематично. В Windows им может послужить как MS Office, так и обычный «Блокнот».

Написание

Начало программ и их составление – это изучение выбранного ЯП. Когда с синтаксисом пользователь уже разобрался, можно приступать к активным действиям. Ранее указанные инструменты устанавливают на задействованное устройство. Лишь после этого система будет готова к первым проектам.

Для VS

Чтобы программировать на C++ в Visual Studio, потребуется выполнить следующие действия:

  1. Для начала запустить среду разработки.
  2. Выбрать «Файл»-«Создать»-«Проект».
  3. Переключиться в категорию «Общие».
  4. Щелкнуть по надписи «Пустой…».
  5. Придумать название. Пример – Lesson1.
  6. Подтвердить действие.

На экране появится проект. В нем предстоит осуществлять дальнейшие действия. Если часть кода уже имеется на устройстве, можно загрузить ее и продолжить написание.

В обозревателе решений остается кликнуть ПКМ на папке «файлы исходного кода». Там – выбрать «Добавить»-«Создать элемент». Нужно сделать новый документ main.cpp и добавить его в разработку.

Для GCC

В случае с GCC действовать предстоит иначе. Пользователю необходимо создать пустой файл. Далее – открыть через любой текстовый редактор с подсветкой синтаксиса.

Код-пример

В самом начале рассмотрения C++ не нужно проектировать сложный контент. Вот пример кода, который будет реализовываться новичками:

Именно эту запись предстоит вставить в текстовый редактор или VS. При компиляции она образует самостоятельную утилиту.

Синтаксис

C++ обладает непростым синтаксисом. Он предусматривает множество нюансов и особенностей. Вот объяснение того, как функционирует программа, написанная выше:

 

  1. Директива #include отвечает за подключение других файлов в исполняемый код. Если там написано <iostream> — происходит замена строчки на документ iostream.h. Это – стандартная библиотека языка. Отвечает за ввод и вывод.
  2. #include <csrdlib> — еще одна стандартная библиотека. Она нужна для функционирования system.
  3. Using namespace std – указание на то, что клиент изначально будет использовать пространство имен с названием std. Все, написанное после int main() будет автоматически выполняться после запуска ПО.
  4. Count << «Hello, world!» << end; — запись, которая отвечает за вывод на экран надписи в кавычках.

В первой программе на C++ обычно изучают процесс вывода информации на экран. Count – основной оператор, который предстоит использовать. Текст, который хочется вывести на дисплей из командной строки, прописывается в двойных кавычках. End1 отвечает за перевод строчки уровнем ниже.

При завершении работы утилиты без сбоев происходит генерация кода ошибки, равного нулю. Return 0 требуется для передачи сообщения о том, что софт успешно обработан.

Запуск

Для того, чтобы у начинающих не возникло проблем с запуском первой программы на C++, требуется разобраться, как это сделать. В Visual Studio для этого можно задействовать сочетания Ctrl + F5. В GCC – выполнить такие команды:

Если код написан грамотно, он выведет на экран окно с приложением. В противном случае возникнет сообщение об ошибке.

.NET Core в действии: пишем бота для telegram.

В предыдущей статье я немного затронул .NET Core и ввел некоторые определения. Этой статьей я хочу показать как с ним работать и что из этого может получиться. Примером — будет простой бот для telegram. Помимо самого кода, в этой статье я постараюсь объяснить некоторые принципы проектирования Web приложений на C# и .NET Core 2.0, а также рассказать о некоторых особенностях telegram, и дать некоторую литературу по данному направлению. Для всех ГУРУ и тех кому не терпится посмотреть: смотрите вот этот репозиторий на github. Тут уже находится необходимый шаблон для написания бота (кстати лежит он у меня довольно давно и эта и предыдущая статьи должны были выйти раньше, но время. его как всегда не хватает). Ну хватит лирики. Погнали кодить!

Шаг 1: Теория.

Тут я расскажу о ASP.NET Core 2.0, немного затрону его отличия от обычного человеческого ASP.NET, расскажу о паттерне проектирования MVC. Знающие люди смело могут перейти к шагу 2. Вся литература все равно будет продублирована в конце. Вы ничего не пропустите.

Еще немного теории о .NET Core…

Платформа ASP.NET Core представляет технологию от компании Microsoft, предназначенную для создания различного рода веб-приложений: от небольших веб-сайтов до крупных веб-порталов и веб-сервисов.

С одной стороны, ASP.NET Core является продолжением развития платформы ASP.NET. Но с другой стороны, это не просто очередной релиз. ASP.NET Core фактически делает революцию всей платформы, ее качественное изменение. Как вы уже поняли, ASP.NET Core работает поверх кросс-платформенной среды .NET Core, которая может быть развернута на основных популярных ОС: Windows , Mac OS X , Linux .

Как следует из примера 2 прошлой статьи — теперь развертывания сайта на ASP.NET Core может производится внутри самого приложения. Для этого используется кросс-платформенный веб-сервер Kestrel , который уже строен “из коробки”, однако традиционный IIS — никто не отменял. Это позволяет осуществлять более гибкую настройку: пользуетесь Linux и хотите демонезировать приложение (обернуть в Service) — пожалуйста, обернуть сайт в docker — никаких проблем. С .NET Core все стало гораздо прозрачнее и понятней.

Благодаря модульности фреймворка все необходимые компоненты веб-приложения могут загружаться как отдельные модули через Nuget (он к стати совсем недавно стал работать намного быстрее, хотя иногда он тупит и тогда приходится идти пить чай после команды restore). В добавок, в .NET Core 2.0, в отличие от 1.0 больше не обязательно использовать библиотеку System.Web.dll .

ASP.NET Core включает в себя фреймворк MVC , который объединяет функциональность MVC, Web API и Web Pages. В предыдущих версии платформы данные технологии реализовались отдельно и поэтому содержали много дублирующей функциональности. Сейчас же они объединены в одну программную модель ASP.NET Core MVC. А Web Forms полностью ушли в прошлое.

Кроме объединения вышеупомянутых технологий в одну модель в MVC был добавлен ряд дополнительных функций.

Одной из таких функций являются тэг-хелперы (tag helper), которые позволяют более органично соединять синтаксис html с кодом С#. Да, в отличии от ASP.NET хтмл фойлы тепеть хранятся в новом формате CSHTML. Признаюсь, когда я впервые увидел tag helper-ы с их @ и < - у меня потекла кровь из глаз. почему-то сразу вспомнился qBASIC , 1С , template-ы в крестах и GOTO (Никогда не пишите на qBASIC))). Но после пары часов я понял, что это в прицепе помогает (хотя нет, это ужасно и я стараюсь их избегать). И напоследок, для обработки запросов теперь используется новый конвейер HTTP, который основан на компонентах Katana и спецификации OWIN . А его модульность позволяет легко добавить свои собственные компоненты. Да, web-api стало писать намного удобнее.

Резюмируя, можно выделить следующие ключевые отличия ASP.NET Core от предыдущих версий ASP.NET:

  • Новый легковесный и модульный конвейер HTTP-запросов
  • Возможность развертывать приложение как на IIS, так и в рамках своего собственного процесса
  • Использование платформы .NET Core и ее функциональности
  • Распространение пакетов платформы через NuGet
  • Интегрированная поддержка для создания и использования пакетов NuGet
  • Единый стек веб-разработки, сочетающий Web UI и Web API
  • Конфигурация для упрощенного использования в облаке
  • Встроенная поддержка для внедрения зависимостей
  • Расширяемость
  • Кроссплатформенность: возможность разработки и развертывания приложений ASP.NET на Windows, Mac и Linux
  • Развитие как open source, открытость к изменениям

Паттерн MVC и с чем его едят.

По словам Википедии, паттерн (англ. design pattern) — повторимая архитектурная конструкция, представляющая собой решение проблемы проектирования в рамках некоторого часто возникающего контекста. Например способ проектирования «сверху вниз» можно отнести к одним из первых паттернов проектирования.

Model-View-Controller. MVC — это фундаментальный паттерн, который нашел применение во многих технологиях, дал развитие новым технологиям и каждый день облегчает жизнь разработчикам.

Впервые паттерн MVC появился в языке SmallTalk . Разработчики должны были придумать архитектурное решение, которое позволяло бы отделить графический интерфейс от бизнес логики, а бизнес логику от данных. Таким образом, в классическом варианте, MVC состоит из трех частей, которые и дали ему название.

Model.

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

Модель обладает следующими признаками:

  • Модель — это бизнес-логика приложения;
  • Модель обладает знаниями о себе самой и не знает о контроллерах и представлениях;
  • Для некоторых проектов модель — это просто слой данных (DAO, база данных, XML-файл);
  • Для других проектов модель — это менеджер базы данных, набор объектов или просто логика приложения;

В обязанности Представления входит отображение данных полученных от Модели. Однако, представление не может напрямую влиять на модель. Можно говорить, что представление обладает доступом «только на чтение» к данным.

Представление обладает следующими признаками:

  • В представлении реализуется отображение данных, которые получаются от модели любым способом;
  • В некоторых случаях, представление может иметь код, который реализует некоторую бизнес-логику. Но только в некоторых случаях(!) и вообще я этого не говорил:-)

Примеры представления: HTML-страница, WPF форма, Windows Form.

Controller.

Контроллер обеспечивает «связи» между пользователем и системой . Контролирует и направляет данные от пользователя к системе и наоборот. Использует модель и представление для реализации необходимого действия.

  • Контроллер определяет, какие представление должно быть отображено в данный момент;
  • События представления могут повлиять только на контроллер.контроллер может повлиять на модель и определить другое представление.
  • Возможно несколько представлений только для одного контроллера;

Основная идея этого паттерна в том, что и контроллер и представление зависят от модели, но модель никак не зависит от этих двух компонент.

Итак, контроллер перехватывает событие извне и в соответствии с заложенной в него логикой, реагирует на это событие изменяя Mодель, посредством вызова соответствующего метода. После изменения Модель использует событие о том что она изменилась, и все подписанные на это события Представления, получив его, обращаются к Модели за обновленными данными, после чего их и отображают.

Начинающие программисты очень часто трактуют архитектурную модель MVC как пассивную модель MVC: модель выступает исключительно совокупностью функций для доступа к данным, а контроллер содержит бизнес-логику. В результате — код моделей по факту является средством получения данных из СУБД, а контроллер — типичным модулем, наполненным бизнес-логикой. В результате такого понимания — MVC-разработчики стали писать код, который Pádraic Brady (известный в кругах сообщества «Zend Framework» (Толстые, тупые, уродливые контроллеры или ТТУК).

Наиболее наглядно эта проблема описана статье The M in MVC: Why Models are Misunderstood and Unappreciated Pádraic Brady. Вот перевод этой статьи.

Но в объектно-ориентированном программировании используется активная модель MVC, где модельэто не только совокупность кода доступа к данным и СУБД, но и вся бизнес-логика; также, модели могут инкапсулировать в себе другие модели. Контроллеры же, — как элементы информационной системы, — ответственны лишь за:

  • приём запроса от пользователя;
  • анализ запроса;
  • выбор следующего действия системы, соответственно результатам анализа (например, передача запроса другим элементам системы).

Только в этом случае контроллер становится «тонким» и выполняет исключительно функцию связующего звена (glue layer) между отдельными компонентами информационной системы.

Ох уж эти паттерны… Я надеюсь что мои формулировки не взорвали моит немногочисленным читателям мозг. Если вы не поняли то, что я писал — не переживайте. Паттерны вообще не самая простая тема, а среди всех MV- паттернов — MVC, на мой взгляд, вообще является одним из самых сложных для понимания. Так или иначе я постарался доступно объяснить его суть. Это одна из тех вещей, которая коде выглядит не так страшно и более понятно. По этому погнали!

Шаг 2: Практика.

И так запускаем нашу любимую Visual Studio 2017 — создаем новый проект с названием TelegrammAspMvcDotNetCoreBo t: .NET Core -> Веб приложение .NET Core. Тип приложения: WebAPI, Версия платформы: .NET Core 2.0.

Web API в ASP.NET Core

Проект, который создается в Visual Studio, будет во многом напоминать проект для MVC за тем исключением, что в нем не будет представлений.

Web API в ASP.NET Core

Первым делом переименуем ValuesController.cs в MessageController , и выпилим оттуда все. Оставим пустой класс с обработкой GET -запроса:

Запустим нашу прилку и перейдем по ссылке localhost:XXXX/api/message/update . Получили результат Method GET unuvalable (ура мы крутые прогеры!).

Model first.

Для написания проекта будем использовать подход “model first”. Он заключается в том, что сначала необходимо разработать модель приложения и написать логику, затем нарисовать Представление, а уже потом склеить это дело контроллером.

Итак, нам нужен сам бот для телеги. Давайте опишем его модель. Пошли кодить? Неет. Сначала обдумаем а как эту модель реализовать.

У бота есть несколько параметров конфигурации: токен, имя, и url сайта, где он лежит. Значит это настройки бота. и их можно описать в отдельном классе. Создадим папку Models а в ней класс AppSettings.cs:

Отлично! Теперь опишем бота? Подождите. Бот такая сущность которая должна содержать команды и выполнять их. А значит нам нудны еще эти самые команды. Как должна выглядеть команда? Каждая команда как-то называется, значит содержит свойство Name. Команда должна определять вызвали ее или нет: содержать булеву функцию Contains(. ) . И уметь выполнять себя — Execute(. ) . И последнее: команд может быть много, значит нужен какой то абстрактный класс.

Теперь создадим папку Commands внутри папки Models и запихнем туда класс Command.cs:

Здесь Execute возвращает не void, а Task, так как команда может выполняться и асинхронно.

Ну что же, пришла пора писать бота. Любой телеграм бот должен содержать клиента TelegramBotClient, а также наш бот должен содержать команды. Их будет много, а значит нам нужна их коллекция. К томуже бот должен уметь возвращать TelegramBotClient-а для вызова его из команд.

Создаем класс Bot.cs:

Я думаю, комментарии излишни.

Теперь научим его приветствовать нас. Добавим класс StartCommand.cs:

Осталось сконфигурировать бота, и сказать нашему приложению, что бот у нас есть. Идем в класс Startup и в методе Configure приписываем в конец:

Финальный аккорд. Добавим клея!

Теперь наш контроллер научился обрабатывать сообщения из телеги. Осталось только залить это дело на сервер, и получить ключ от botFather.

В нашем боте мы используем WebHook и для него необходимы HTTPS соединение + Домен. Если вам лень замораживаться, то вы всегда можете задиплоить его на Azure. Не забудьте задать ему URL перед заливкой.

Литература

.Net Core 2.0 вышла совсем недавно, а по этому по ней нет русскоязычной литературы. Честно обошел весь дом книги на Невском, и библиоглобус в Москве. В первом случае вообще нет какой-то внятной литературы (удивление), удалось найти только по .Net Core 1.0, да и то сомнительного качества (я надеюсь Петербуржцы не будут кидать в меня камнями). В Москве выбор чуть больше, но вся русскоязычная литература опять же по версии 1.0. Возможно, я не там искал, тогда буду рад какой-либо информации.

Вот скромный список того, что удалось найти:

Как видите список даже англоязычной литературы ограничивается тремя книгами. А официальных книг от MS нет даже по первой версии. Но метод научного тыка никто не отменял!

Как создать свое первое приложение Windows Forms (Winforms) в Visual Studio?

Как создать свое первое приложение Windows Forms (Winforms) в Visual Studio

Изучение

Освойте Microsoft Visual Studio и разрабатывайте собственные приложения с помощью Windows Forms практически без написания кода.

Windows Forms — это платформа, доступная в Visual Studio, которая позволяет создавать настольные приложения с помощью графического пользовательского интерфейса. Это позволяет вам щелкать и перетаскивать виджеты, такие как кнопки или метки, прямо на холст и управлять свойствами каждого виджета, такими как размер шрифта, цвет или граница.

В этой статье простой конвертер градусов Цельсия в градусы Фаренгейта будет использоваться в качестве примера для изучения основ настройки приложения Windows Form. В этом руководстве используется Visual Studio 2019 Community Edition.

Как создать проект Windows Forms в Visual Studio

Сначала создайте проект в Visual Studio.

  1. Откройте Visual Studio и выберите Создать новый проект.
  2. Visual Studio предоставит вам список шаблонов проектов, из которых вы можете выбрать.
  3. Чтобы создать приложение Windows Forms, найдите приложение Windows Formи выберите его из списка шаблонов. Как только это будет выбрано, нажмите » Далее». здать приложение Windows Forms, найдите приложение Windows Form
  4. Добавьте имя и местоположение для проекта и нажмите » Далее». Расположение — это каталог, в котором будут храниться файлы кода. мя и местоположение для проекта и нажми
  5. На следующем экране сохраните выбор по умолчанию.NET Core 3.1.
  6. Щелкните Создать. ните Созда
  7. Когда Visual Studio завершит создание проекта, он откроется. l Studio завершит создание проекта, он открое

Как добавить элементы на холст проекта

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

Чтобы создать пользовательский интерфейс приложения, добавьте на холст такие виджеты, как кнопки или текстовые поля.

  1. Откройте вкладку «Вид» в верхней части окна и выберите » Панель инструментов «. ерхней части окна и выбери
  2. Это добавит панель инструментов в левую часть приложения. Выберите значок булавкив правом верхнем углу панели инструментов, чтобы закрепить его там навсегда.
  3. Здесь вы можете перетащить любой виджет из панели инструментов на холст. Выделите кнопку на панели инструментов и перетащите ее на холст. десь вы можете перетащить любой виджет из панели инстру
  4. Перетащите на холст еще два текстовых поля вместе с тремя метками (две метки для каждого текстового поля и одна метка для заголовка в верхней части приложения). е два текстовых поля вместе с тремя метками (две метки для каждо
  5. Каждый виджет на холсте имеет связанные с ним свойства. Выделите виджет, чтобы отобразить окно свойствв правом нижнем углу Visual Studio, в котором перечислены все свойства этого виджета. Эти свойства могут включать текст, имя, размер шрифта, границу или выравнивание выделенного виджета.
  6. На данный момент текст этих виджетов по-прежнему говорит label1, label2или button1. Выберите виджет label1и отредактируйте свойство Text в окне свойств, указав «Цельсий в Фаренгейт». Измените размер шрифта на 22pt. данный момент текст этих виджетов по-прежнему говорит labe
  7. Аналогичным образом отредактируйте свойства других виджетов на холсте, чтобы они были следующими:

Виджет

Имущество

Новое значение

Как обрабатывать события и писать код в коде программной части

Виджеты на холсте можно привязывать к событиям. События могут включать в себя такие вещи, как нажатие кнопки, изменение текста внутри текстового поля или выбор определенного переключателя. Когда происходят эти события, это может привести к срабатыванию части кода в программном коде.

C# — это язык, используемый при создании Windows Forms. Если вы еще не использовали C#, есть много практических причин для изучения программирования на C#.

Для этого конкретного приложения добавьте событие к кнопке » Рассчитать «, чтобы инициировать выполнение части кода при нажатии этой кнопки.

1. Дважды щелкните кнопку » Рассчитать«, чтобы автоматически открыть Form1.cs с новым методом Event:

2. Здесь вы добавите код, который будет выполнять расчет градусов Цельсия по Фаренгейту и отображать результат в текстовом поле Фаренгейта. Для этого вам нужно иметь возможность прочитать значение из текстового поля Цельсия и изменить текстовое поле Фаренгейта, чтобы отобразить результат.

3. Вернитесь на холст и повторно отредактируйте свойства, как показано ранее. На этот раз отредактируйте свойство Nameдля текстовых полей Цельсия и Фаренгейта. Эти имена можно использовать для ссылки на текстовые поля в коде.

Виджет Имущество Новое значение
Текстовое поле Цельсия Имя ЦельсияTextBox
Текстовое поле Фаренгейта Имя по ФаренгейтуTextBox

4. Вернитесь к функции calculateButton_Click в Form1.cs.

5. Теперь на текстовое поле Celsius можно ссылаться в коде, используя имя «celsiusTextBox». Введенное пользователем значение Цельсия сохраняется в его свойстве Text. Однако, поскольку это строка, разберите ее на двойную, чтобы включить ее в будущие расчеты по Фаренгейту.

private void calculateButton_Click(object sender, EventArgs e)
<
// Get the value that the user entered in the Celsius Text Box
double celsiusValue = Double.Parse(celsiusTextBox.Text);
>

6. Переменная celsiusValue теперь хранит значение, введенное пользователем в текстовом поле Celsius. Формула для преобразования градусов Цельсия в градусы Фаренгейта: (celsiusValue * 9 / 5) + 32.Таким образом, результат теперь можно рассчитать и сохранить в текстовом поле Фаренгейта.

private void calculateButton_Click(object sender, EventArgs e)
<
// Get the value that the user entered in the Celsius Text Box
double celsiusValue = Double.Parse(celsiusTextBox.Text);
// Apply the calculation
double result = (celsiusValue * 9 / 5) + 32;
// Store the result in the Fahrenheit Textbox
fahrenheitTextBox.Text = result.ToString();
>

Как запускать и отлаживать программу Windows Forms

Запуск программы Windows Forms в Visual Studio

Теперь, когда пользовательский интерфейс и логика кода настроены, запустите программу, чтобы увидеть, как она работает.

ь программу, выберите зеленую стрелку вверху па

1. Чтобы запустить программу, выберите зеленую стрелку вверху панели инструментов в Visual Studio.

ки проекта добавьте значение в текстовое поле Цельсия и нажмите к

2. После загрузки проекта добавьте значение в текстовое поле Цельсия и нажмите кнопку » Рассчитать». Это добавит результат в текстовое поле по Фаренгейту.

3 Если программа размыта во время выполнения, вероятно, ваше приложение не поддерживает DPI. Это может вызвать проблемы с масштабированием и разрешением, поэтому его необходимо включить.

4. Щелкните правой кнопкой мыши проект TemperatureConverterв обозревателе решений. Выберите Добавить, затем выберите Новый элемент.

ите файл манифеста приложения и нажми

5. Найдите файл манифеста приложения и нажмите » Добавить «.

6. Скопируйте следующий код в новый файл app.manifest как дочерний элемент тега сборки (если код уже сгенерирован, просто раскомментируйте его).

7. Чтобы это изменение вступило в силу, перезапустите программу. Нажмите красную кнопку остановки в верхней части панели инструментов, затем снова нажмите зеленую кнопку воспроизведения.

Отладка программы Windows Forms

Вы можете отладить программу, если логика вашего приложения Windows Forms не работает должным образом.

лжить работу программы, нажмите зеленую стре

  1. Вернитесь к функции calculateButton_Click в Form1.cs и щелкните в любом месте серой полосы в крайнем левом углу экрана. Это добавит точку останова, которая обозначена красным кружком.
  2. Нажмите кнопку «Рассчитать» еще раз, чтобы запустить этот метод. Программа приостановится, когда достигнет точки останова, чтобы показать все значения, хранящиеся в переменных в этой точке.
  3. Чтобы продолжить работу программы, нажмите зеленую стрелку » Продолжить» в верхней части панели инструментов.

Запуск программы с помощью исполняемого файла

Если вы не хотите запускать свою программу через Visual Studio, используйте автономный исполняемый файл для программы. Это автоматически генерируется.

Перейдите к исполняемому файлу, который можно найти здесь:

Нажмите на исполняемый файл, чтобы запустить программу напрямую.

Добавление дополнительных элементов в форму Windows

Надеюсь, теперь у вас есть общее представление об основной структуре приложения Windows Form. Вы можете продолжить изучение дополнительных функций Windows Forms, поэкспериментировав с новыми виджетами и углубившись в другие различные события, которые можно обрабатывать.

Как только вы лучше познакомитесь с Windows Forms, вы сможете приступить к созданию более сложных приложений. Вы также можете изучить многие другие способы создания приложений на рабочем столе Windows.

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *