6.89M
Категория: ПрограммированиеПрограммирование

CSharp2ClientServer

1.

Клиент-серверная разработка под .Net на языке
C# (40 а.ч.)
Кораблин Александр Игоревич
specialist.ru

2.

Программа курса
1. Многопоточность (12а.ч.)
Выполнение запросов к БД
Асинхронное программирование
Лабораторная работы
Понятие потоков. Класс Thread
3. Создание сервисов (12 а.ч.)
Синхронизация потоков
Понятие сервисов
Библиотека Task Parallel Library (TPL)
Создание REST сервисов на WebAPI
Асинхронные методы, ключевые слова async и
await
Создание сервиса gRPC
Parallel LINQ
Лабораторная работа
2. Работа с базами данных с использованием Entity
Framework Core (12 а.ч.)
Что такое ORM и EFC
Подключение к БД
Базовые CRUD операции
Миграция
Проектирование моделей (атрибуты, FluentAPI)
Потоковая передача
Предоставление доступа к данным
Лабораторная работа
4. Рефлексия - Reflection, взаимодействие с
библиотеками C (4 а.ч.)
Введение в рефлексию. Класс System.Type
Получение информации о типах
Динамическая загрузка и позднее связывание
Навигационные свойства
Вызов функций библиотек С, передача
параметров.
Отношения моделей
Лабораторная работа
2

3.

Многопоточность
Способность
программы
выполнять
параллельно
несколько действий
В
реальному
приложении
обычно
требуется
одновременно («параллельно») выполнять множество
действий:
Расчетные действия
Взаимодействие с пользователем
Взаимодействие с внешними службами по сети
Взаимодействие с базой данных и т.д.
Серверные приложения обычно также работают в
многопоточном режиме, т.к. должны обрабатывать
множество параллельных запросов от клиентов.
3

4.

Понятие «Потока выполнения»
(«Поток» - Thread)
Поток выполнения или просто Поток (Thread) – это часть
кода программы, представляющей из себя набор команд,
выполняющихся последовательно друг за другом.
В программе (в рамках одного процесса) может быть
запущенно несколько параллельно выполняющихся
потоков.
Для выполнения команд потока ему выделяется квант
времени процессора (ядра процессора).
В .Net для работы с потоками есть класс Thread из
пространства имен System.Threading
4

5.

Класс Thread
ExecutionContext контекст выполнения потока
IsAlive
работает ли поток в текущий момент
IsBackground
является ли поток фоновым
Name
имя потока
ManagedThreadId
идентификатор текущего потока
Priority
приоритет потока (enum ThreadPriority)
ThreadState
состояние потока (enum ThreadState)
static CurrentThread статическое
обратиться к текущему потоку.
свойство,
static Sleep()
останавливает
текущий
определенное количество миллисекунд
позволяющее
поток
на
Interrupt() прерывает поток, который находится в состоянии
WaitSleepJoin
Join()
дожидается завершения другого потока,
блокируя текущий
Start()
запускает поток
5

6.

Enum ThreadState
Aborted поток остановлен, но пока еще окончательно не
завершен
AbortRequested для потока вызван метод Abort, но
остановка потока еще не произошла
Background поток выполняется в фоновом режиме
Running поток запущен и работает (не приостановлен)
Stopped поток завершен
StopRequested поток получил запрос на остановку
Suspended поток приостановлен
SuspendRequested поток получил запрос на приостановку
Unstarted поток еще не был запущен
WaitSleepJoin поток заблокирован в результате действия
методов Sleep или Join
6

7.

Запуск потоков
Вариант 1
Делегат public delegate void ThreadStart();
Конструктор new Thread(ThreadStart)
или new Thread(ThreadStart, Int32 /*размер стека*/)
Метод Start() для запуска потока
Вариант 2
Делегат public delegate void ParameterizedThreadStart(object? obj);
Метод Start(object?) для запуска потока
Вариант 3
Определить метод в собственном классе, передав параметры
через свойства объекта (при его создании)
7

8.

Лабораторная 1.1
Создать два потока, каждый из которых принимает на
вход 2 параметра: начальное и конечное число
(диапазон).
Каждый из потоков должен вывести числа в указанном
диапазоне.
Запустить потоки на параллельное выполнение
Использовать любой из вариантов передачи параметров
8

9.

Синхронизация потоков
Синхронизация потоков основана на том, что один или
несколько потоков переходят в состояние ожидания
(WaitSleepJoin), до тех пор пока не произойдёт некоторое
событие.
Синхронизация по завершению другого потока – метод
Join()
Синхронизация по объекту– оператор lock
Синхронизация с помощью монитора
Синхронизация штатными классами: AutoResetEvent,
Mutex, Semaphore
9

10.

Лабораторная 1.2
Создать два потока, каждый из которых выводит числа от
1 до 100. Второй поток должен быть так синхронизирован
с первым, чтобы он начинал вывод своих чисел только
после завершения вывода первым
Запустить потоки на параллельное выполнение
Убедится что числа второго потока выводятся только
после первого
Провести эксперимент: поменять порядок запуска
потоков, поставив между запусками задержку в 1с
10

11.

Оператор lock
Организует т.н. «критическую» секцию кода
В один момент времени только один поток может
выполнять критическую секцию (для данного объекта
синхронизации)
lock (объект_синхронизации)
{
// Операторы критической секции
}
11

12.

Класс System.Threading.Monitor
void Enter(object obj) получает в эксклюзивное владение объект,
передаваемый в качестве параметра.
void Enter(object obj, bool acquiredLock) acquiredLock указывает, получено ли
владение над объектом из первого параметра
void Exit(object obj) освобождает ранее захваченный объект
bool IsEntered(object obj) возвращает true, если монитор захватил объект obj
void Pulse (object obj) уведомляет поток из очереди ожидания, что текущий
поток освободил объект obj
void PulseAll(object obj) уведомляет все потоки из очереди ожидания, что
текущий поток освободил объект obj. После чего один из потоков из очереди
ожидания захватывает объект obj.
bool TryEnter (object obj) пытается захватить объект obj. Если владение над
объектом успешно получено, то возвращается значение true
bool Wait (object obj) освобождает блокировку объекта и переводит поток в
очередь ожидания объекта. Следующий поток в очереди готовности объекта
блокирует данный объект. А все потоки, которые вызвали метод Wait,
остаются в очереди ожидания, пока не получат сигнала от метода
Monitor.Pulse или Monitor.PulseAll, посланного владельцем блокировки.
12

13.

Класс System.Threading.AutoResetEvent
Reset() сбрасывает сигнал, блокируя потоки
Set() устанавливает сигнал, разблокируя один или
несколько потоков
WaitOne() блокирует текущий поток, пока не получит
сигнал
static WaitAll() блокирует текущий поток, ожидая все
сигналы
static WaitAny() блокирует текущий поток, ожидая один из
нескольких сигналов
13

14.

Классы System.Threading.Mutex и
System.Threading.Semaphore
WaitOne() блокирует текущий поток, пока не освободится
mutex
ReleaseMutex() освобождает mutex
Semaphore (int initialCount, int maximumCount) initialCount начальное количество потоков, maximumCount максимальное количество потоков, которые имеют доступ
к общим ресурсам
WaitOne() ожидает получения свободного места в
семафоре
Release() освобождает место в семафоре
14

15.

Лабораторная 1.3
Создать два потока, которые будут работать параллельно,
обрабатывая одно значение типа double
Первый поток вычисляет значения косинуса, выводит
результат и сохраняет его в ту же переменную
Второй поток вычисляет значения арккосинуса, выводит
результат и сохраняет его в ту же переменную
Потоки нужно синхронизировать таким образом, чтобы
она работали в противофазе.
15

16.

Библиотека Task Parallel Library (TPL)
Пространство имен System.Threading.Tasks
Абстрагирует понятие задачи (Task), не привязывая её к
конкретному потоку
Объект класса Task описывает отдельную задачу, которая
будет выполняться асинхронно (параллельно) в одном из
процессов из пула потоков
16

17.

Создание Task
Использование делегата Action
Task task1 = new Task(new Action(MyMethod));
Использование анонимного делегата
Task task2 = new Task(delegate
{
Console.WriteLine("Task 2 reporting");
});
Использование лямбда-выражения
Task task2 = new Task(() =>
{
Console.WriteLine(" Task 2 reporting");
});
17

18.

Выполнение задачи
Запуск задачи:
Task.Start()
static Task.Factory.StartNew()
Task.Run()
Ожидание завершения:
Task.Wait()
static Task.WaitAll()
static Task.WaitAny()
18

19.

Возврат значения из задачи
Используйте Task<TResult>, типизировав его
типом результата
Вернуть значение указанного типа как результат
выполнения
Task<string> task1 = Task.Run<string>( () =>
DateTime.Now.DayOfWeek.ToString() );
Получить результат через свойство Result
Console.WriteLine("Today is {0}", task1.Result);
19

20.

Управление длительными операциями
Для
того,
чтобы
иметь
возможность
отменять
выполнение длительной операции нужно создать
CancelationToken и передать его задаче
var cancelTokenSource = new CancellationTokenSource();
CancellationToken token = cancelTokenSource.Token;
Вызвать метод CancellationTokenSource.Cancel(), который
устанавливает
для
свойства
CancellationToken.IsCancellationRequested значение true
Внутри задачи разработчик должен сам решить, как её
корректно отменять
20

21.

Связанные задачи
Задачи, являющиеся продолжением друг друга, могут образовывать
цепочки задач.
Метод
Task.ContinueWith()
предыдущей
связывает
следующую
задачу
с
Следующая задача запускается, когда завершится предшествующая
Предшествующая задача
вычисления следующей
может
передать
результат
своего
Из одной задачи можно запустить другую. Такая задача называется
вложенной (Nested) и является достаточно независимой от той, из
которой она запущена.
Вложенную задачу можно сделать дочерней (Child),
TaskCreationOptions.AttachedToParent при создании задачи.
указав
Дочерняя (Child) и родительская (Parent) задачи тесно связаны друг с
другом – родительская задача не завершится, пока работают
дочерние, родительская также получает исключения от дочерних.
21

22.

Обработка исключений
Если из задачи выбрасывается необработанное исключение, то оно
оказывается в потоке, запустившем задачу (joined thread)
Задача может быть связана с другими задачами, поэтому может быть
выброшено несколько исключений
try
{
task1.Wait();
}
catch(AggregateException ae)
{
foreach(var inner in ae.InnerExceptions)
{
// Обработать каждое исключение
}
}
22

23.

Потокобезопасные коллекции
Пространство
имен
System.Collections.Concurrent
содержит набор классов и интерфейсов для работы с
потокобезопасными коллекциями:
ConcurrentBag<T> неупорядоченный набор элементов
ConcurrentDictionary<TKey, TValue> потокобезопасный
аналог Dictionary<TKey, TValue>
ConcurrentQueue<T> потокобезопасный аналог Queue<T>
ConcurrentStack<T> потокобезопасный аналог Stack<T>
IProducerConsumerCollection<T> описывает функционал
источник/подписчик. Реализован в ConcurrentBag<T>,
ConcurrentQueue<T> и ConcurrentStack<T> (реализуют
блокировки read/write)
BlockingCollection<T>
обертка
для
IProducerConsumerCollection<T>
23

24.

Лабораторная 1.4
Используя проект SocketServer и SocketClientMT для того
чтобы добиться ошибок клиента (не все запросы
клиентов обрабатываются однопоточным сервером)
Создать новый проект SocketServerMT (на основе
SocketServer), превратив сервер в многопоточный,
используя Task
Добиться, чтобы все запросы многопоточного клиента
успешно обработались
24

25.

Асинхронное программирование
APM – Asynchronous Programming Model, подход основан
на использовании интерфейса IAsyncResult. APM появился
вместе с .Net в 2000 г.
Устарел
EAP – Event-based Asynchronous Pattern, подход из .Net
Framework 2.0.
Устарел
TAP – Task-based Asynchronous Pattern. Рекомендуемый
стиль
25

26.

Использование async и await
В заголовок метода добавляется модификатор async
Внутри метода с модификатором async можно исполоьзовать
оператор await с параметром в виде задачи (Task). Оператор await
дождётся завершения задачи, не блокируя поток выполнения. Если
задача параметризирована типом возвращаемого значения, то await
вернёт результат.
private async void btnLongOp_Click(object sender, RoutedEventArgs e)
{
...
Task<string> task1 = Task.Run<string>(() =>
{
...
}
lblResult.Content = await task1;
}
26

27.

Создание асинхронных методов
Оператор await используется для ожидания завершения
асинхронной задачи
Если синхронный метод возвращал void, то его
асинхронная замена должна иметь тип возвращаемого
значения Task, при этом return быть не должно
Если синхронный метод возвращал значение типа T, то
его
асинхронная
замена
должна
иметь
тип
возвращаемого значения Task<T>, но return должен всё
также возвращать значение типа T
27

28.

28

29.

Обработка исключений в асинхронных
методах
Можно использовать обычные операторы try/catch для
обработки исключений в асинхронных блоках
Подписавшись на событие
TaskScheduler.UnobservedTaskException обработчик для
непойманных исключений
TaskScheduler.UnobservedTaskException +=
(object sender, UnobservedTaskExceptionEventArgs e) =>
{
// Respond to the unobserved task exception.
}
29

30.

Лабораторная 1.5
В проекте BinaryBalancedTree распараллелить метод
подсчета веса дерева используя асинхронные методы.
Замерить
время
выполнения
однозадачного
и
многозадачного метода, проверить результат
Добиться ускорения в многозадачном варианте на
многоядерном процессоре (использовать Build Release)
30

31.

Запуск асинхронных задач с помощью класса
Parallel
Parallel.Invoke
параллельно
позволяет
запустить
несколько
задач
Parallel.Invoke( () => MethodForFirstTask(),
() => MethodForSecondTask(),
() => MethodForThirdTask() );
Parallel.For позволяет выполнять итерации цикла
параллельно
Parallel.ForEach позволяет выполнять итерации цикла
переборки параллельно
PLINQ позволяет распараллелить выполнение LINQ
запроса
31

32.

Parallel LINQ (PLINQ)
AsParallel() позволяет распараллелить запрос к источнику
данных
ForAll() выполняет операцию в своём потоке
AsOrdered() упорядочивает данные в соответствии с
исходным порядком
AsUnordered() отключает упорядочивание
WithCancellation(CancellationToken) отмена операции
32

33.

Лабораторная 1.6
В проекте Integral распараллелить метод расчета
интеграла используя Parallel и/или другие механизмы
(Thread, Task, async).
Замерить
время
выполнения
однозадачного
и
многозадачного метода, проверить результат
Добиться ускорения в многозадачном варианте на
многоядерном процессоре (использовать Build Release)
33

34.

Entity Framework Core
ORM (Object-Relation-Mapping)
отображение
объектно-реляционное
Решает задачи связывание объектных структур данных
(обычно реализованных на объектно-ориентированных
языках программирования) и реляционных структур,
поддерживаемых
реляционными
базами
данных,
ставшими стандартом де-факто в области хранения
данных
EFC является дальнейшим развитие Entity Framework,
давно использовавшемся .Net разработчиками
Проект Open Source https://github.com/dotnet/efcore
34

35.

Понятия EFC
Классы Сущностей (Entity) – классы, объекты которых
сохраняются в реляционную базу данных.
EFC отвечает за генерацию и выполнение необходимых
SQL запросов как для обновления базы на основе
изменений объектов сущностей, так и для загрузки
данных объектов из базы
Фактически EFC выступает в роли объектной надстройки
над реляционной базой
Мы можем говорить, что внешне это выглядит как
объектная база данных, работающая с наборами
множеств разнотипных объектов, при в качестве
постоянного хранилища используется реляционная база
EFC предоставляет возможность выполнять LINQ запросы
к виртуальным множествам объектов в базе, которые
автоматически
преобразуются
в
SQL
запросы,
выполняются, а на основе результат воссоздаются
объекты в памяти
35

36.

Сущности (Entity) в EFC
Сущность
обладает
набором
свойств,
которые
отображаются (связываются) с колонками реляционных
таблиц.
Такие связи могут быть простыми (одна сущность – одна
таблица) и более сложными (данные сущности могут
сохраняться в нескольких таблицах и наоборот)
Как и таблицы, классы сущностей могут быть связаны друг
с другом в различных отношениях (один-к-одному, одинко-многим, многий-ко-многим), при этом EFC может
работать
с
навигационными
свойствами,
сразу
предоставляющими доступ к связанным сущностям
36

37.

Основные пакеты EFC
Microsoft.EntityFrameworkCore основной пакет EFC
Microsoft.EntityFrameworkCore.SqlServer провайдера для
Microsoft SQL Server и SQL Azure
Microsoft.EntityFrameworkCore.InMemory провайдера базы
данных в памяти
Microsoft.EntityFrameworkCore.Tools
команды
EFC
PowerShell для Visual Studio Package Manager Console,
применяется в Visual Studio для миграций и генерации
классов по готовой базе данных
Microsoft.EntityFrameworkCore.Design
вспомогательные
компоненты EFC, применяемые в процессе разработки
Microsoft.EntityFrameworkCore.Proxies "ленивая загрузка"
(lazy-loading) и прокси отcлеживания изменений
37

38.

Создание приложения
Подключить пакеты EFC, включая пакет провайдера
нужной
базы
данных
(например
Microsoft.EntityFrameworkCore.SqlServer)
Создать класс(ы) сущностей
Создать класс контекста – наследника DBContext,
определив в нём свойства DBSet<Entity> для каждой
сущности
Задать connectionString либо в методе OnConfiguring через
конструктор,
либо
через
конструктор
DBContext(DbContextOptions<ApplicationContext>)
38

39.

Конфигурация JSON
Подключить Microsoft.Extensions.Configuration.Json
Создать appsettings.json
"ConnectionStrings": {
"DefaultConnection": “connection string"
}
IConfiguration config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
config.GetConnectionString("DefaultConnection");
39

40.

Создание классов на основе существующей
БД
Подключить пакет Microsoft.EntityFrameworkCore.Tools
В окне Package Manager Console Visual Studio выполнить
Scaffold-DbContext “connectionstring“ provider
например
Scaffold-DbContext
“Server=(localdb)\mssqllocaldb;Database=persondb;Trusted_Connection
=True;“ Microsoft.EntityFrameworkCore.SqlServer
Или аналогично в консоли (при наличии .NET CLI)
dotnet ef dbcontext scaffold “connectionstring“ provider
(если не установлен установить: dotnet tool install --global dotnet-ef )
40

41.

Управление базой данных
Свойство Database в DBContext
Database.EnsureCreated() гарантируют, что база данных
будет создана
Database.EnsureDeleted() гарантируют, что база данных
будет удалена
Можно вызывать например в конструкторе класса
контекст или вне него в самой программе.
41

42.

Основные операции с базой данных
Для
извлечения
данных
используем
свойства
DBSet<Entity> в классе контекста как источники данных.
Можно использовать в LINQ запросах или напрямую
Помнить
про
отложенное
выполнение
(deferred
execution), сами DBSet не содержат данные в памяти.
Поэтому
для
извлечения
использовать
методы,
вызывающие GetEnumerator() (например ToList())
Методы Add() и Remove() у DBSet для CRUD операций
(изменения отслеживаются автоматически в рамках
контекста)
Метод SaveChanges() контекста сохраняет изменения в
базе данных
42

43.

Журналирование
Метод LogTo() в DbContextOptionsBuilder
позволяет
указать куда выводить журнал при конфигурировании
контекст (в методе OnConfiguring())
43

44.

Лабораторная работа 2.1
Создать класс сущности Course с полями
int Id – идентификатор
string Title – название курса
int Duration - длительность
string? Description – описание курса
Создать класс контекста
Создать json файл с ConnectionString
Реализовать загрузку ConnectionString из json файла
В программе создать контекст, добавить, прочитать,
модифицировать данные
44

45.

Миграция схемы базы данных
Набор действий для обновления схемы базы данных
(например при переходе к новой версии)
В окне Package Manager Console
Add-Migration migration_name
Update-Database
Создание скрипта
Script-Migration
Из кода метод Database.Migrate()
В консоли
dotnet ef migrations add InitialCreate
dotnet ef database update
dotnet ef migrations script
45

46.

Определение моделей данных в EFC
В старых версиях Entity Framework использовалась очень
громоздкая xmlсхема определявшая модели сущностей
(model schema), схему базы данных (storage schema) и их
связь (mapping). В VS присутствует визуальный дизайнер
для этой схемы
Сейчас используется более легковесные варианты:
соглашения (conventions)
разметка с помощью атрибутов (декларативная
аннотации)
Fluent API (императивный способ задания связей,
ограничений и т.д.)
46

47.

Fluent API
Конфигурирование моделей осуществляется в методе
OnModelCreating(ModelBuilder modelBuilder) контекста
Если конфигурация большая, ей можно вынести в
отдельные класса для каждого вида сущностей,
реализующих интерфейс IEntityTypeConfiguration<Entity>
Применить
эти
конфигурации
можно
методом
modelBuilder.ApplyConfiguration(

);
внутри
OnModelCreating
… или использовать метод modelBuilder.Entity(…
… или навесить атрибут
[EntityTypeConfiguration(typeof(EntityConfiguration))]
класс сущности
на
47

48.

Инициализация начальными значениями
Метод modelBuilder.Entity<…>().HasData(…)
Будет выполняться только при:
Миграции данных
При
воссоздании
Database.EnsureCreated()
базы
методом
48

49.

Навигационные свойства
public class Company
{
public int Id { get; set; }
public string? Name { get; set; }
// навигационное свойство
public List<Person> Persons { get; set; } = new();
}
public class Person
{
public int Id { get; set; }
public string? Name { get; set; }
// внешний ключ
public int CompanyId { get; set; }
// навигационное свойство
public Company? Company { get; set; }
}
49

50.

Загрузка связанных данных
При наличии навигационных свойств можно загружать
связанные данные. Есть три стратегии загрузки:
Eager loading (жадная загрузка) метод Include()
Explicit loading (явная загрузка) метод Load()
Lazy loading (ленивая загрузка)
Пакет Microsoft.EntityFrameworkCore.Proxies
Вызвать метод
контекста
UseLazyLoadingProxies()
Навигационные свойства должны
сущностей допускать наследование
быть
при
конфигурировании
виртуальными,
классы
50

51.

Лабораторная 2.2
В существующей базе данных с сущностью Course
добавить сущности Teacher и Student
Установить связи многий-ко-многим между Course и
Teacher, и между Course и Student
Заполнить начальными значениями
Извлечь информацию о взаимодействии преподаватель и
студентов друг с другом (через курсы). Использовать для
этого различные механизмы загрузки (eager, explicit, lazy)
Включить журналирование и изучить генерируемые SQL
запросы при разных механизмах загрузки
51

52.

Сервисы
При
создании
распределенных
приложений,
т.е.
приложений, компоненты которых работают на разных
узлах, важно иметь возможность удаленного вызова
функций – Remote Procedure Call (RPC)
Набор функций (процедур), которые можно удаленно
вызывать, сгруппированных на одном узле называется
сервисом
Для создания сервиса и его клиентов необходима
инфраструктура
(библиотеки),
обеспечивающая
сериализацию, данных, передачу сетевых запросов,
получение ответа, обработку ошибок
Произвольный сервис может иметь собственный набор
функций, образующих его собственное API – контракт
52

53.

REST (REpresentation State Transfer) используют протокол HTTP в качестве
транспорта, одновременно определяют функционал доступа к данным на основе
команд самого протокола HTTP
53

54.

Команды манипулирования ресурсом
54

55.

Фреймворк ASP.NET CORE
ASP.NET Core – фреймворк, предназначенные для
создания веб приложений (сервисов)
Может использовать как веб сервера под Windows (IIS), так
и кроссплатформенные (Kestrel)
Реализует конвейерную обработку запроса, причем в
отличии от предыдущих версий (ASP.NET) конвеер можно
легко настраивать
Для создания классических веб приложений предлагает
использовать шаблон MVC (Model-View-Controller)
ASP.NET CORE WebAPI позволяет создавать REST сервисы
Проект Open Source https://github.com/dotnet/aspnetcore/
55

56.

ASP.NET CORE WebAPI
Есть 2 варианта обработки запросов:
Конфигурирование конвейера и написание собственных EndPoints
– может быть выполнено вручную, также можно сгенерировать
EndPoints для работы с классами сущности Entity Framework Core
Использовать
штатный
механизм
контроллеров,
создав
собственные API-контроллеры. Контроллеры также могут быть
созданы вручную, либо сгенерированы на основе классов
сущностей Entity Framework Core
Поддерживает сериализаторы JSON, XML
Клиентом
может
являться
любая
компонента,
поддерживающая протокол HTTP, написанные как на C#
(например HttpClient), так и на других языках, например
JavaScript в рамках веб приложения (Fetch API)
OpenAPI реализованное в Swagger упрощает создание
клиентов и тестирование сервиса
56

57.

Лабораторная работа 3.1
Используя шаблон WebAPI в VisualStudio создать проект
сервиса доступа к базе данных с курсами
Добавить EFC контекст (из предыдущих лабораторных)
для доступа к данным
Создать сервисы для удаленного доступа ко всем видам
сущностей (включить поддержку OpenAPI через Swagger)
Протестировать с помощью внешней программы
получившиеся сервисы (YAR client в chrome) или через
Swagger
Создать клиента (C# или JavaScript) для получения и
отображения данных, полученных от сервиса (добавив
ссылку на службу OpenAPI используя Swagger)
57

58.

Сервисы gRPC
gRPC - фреймворк, использующий протокол RPC (Remote
Procedure Call) для обмена сообщениями между клиентом
и сервером
Не привязан к конкретному языку, предлагает
собственную систему типов и бинарную сериализацию
Высокая производительность, использование контрактов
(подход “contract-first”), потоковая передача данных в обе
стороны
Язык proto для описания сервиса
Не поддерживается напрямую в JavaScript
58

59.

Лабораторная 3.2
Используя шаблон gRPC в VisualStudio создать проект
сервиса доступа к базе данных с курсами
Добавить EFC контекст (из предыдущих лабораторных)
для доступа к данным
На языке proto описать сервис для доступа к сущности
Course EFC контекста
Создать клиента получения и отображения данных,
полученных от сервиса
59

60.

Reflection - Отражение
Технология, позволяющая программе в процесс своего
выполнения получать информацию о типах, из которых
она состоит, их структуре
Использует метаданные, сохраняемые в сборке при
компиляции
Обеспечивают динамическую загрузку сборок и работу с
неизвестными заранее (на этапе компиляции) типами
Позволяет реализовывать различные расширения,
плагины,
а
также
реализовывать
функционал,
работающий с произвольными типами
Несет дополнительные накладные расходы
60

61.

Вызов функций библиотек C
// Use DllImport to import the Win32 MessageBox
function.
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern int MessageBox(IntPtr hWnd,
String text, String caption, uint type);
// Call the MessageBox function using platform
invoke.
MessageBox(new IntPtr(0), "Hello World!", "Hello
Dialog", 0);
61

62.

Лабораторная 4.1
Создать проект библиотеки (ClassLibrary), скопировав туда
классы сущностей из предыдущих лабораторных
Создать проект консольного приложения, которое
динамически загрузит созданную библиотеку
В загруженной динамически библиотеке перебрать в ней
все публичные классы, в каждом классе перебрать все
публичные свойства
Вывести называние каждого класса со списком свойств и
их типами
62

63.

Учебный центр «СПЕЦИАЛИСТ» –
Ваш путь к успеху
[email protected]
+7 (495) 232-32-16
English     Русский Правила