воскресенье, 30 января 2022 г.

переезд с blogger.com

 blogger.com  стал недоступен в Казахстане (какого то хрена)

буду теперь постить тут: https://www.linkedin.com/in/alik-kim/ 

UPD: теперь - тут - https://qimaliq.wixsite.com/aliqcomp 

UPD: эмм, эта площадка стала доступна, но я уже переехал, так что все :)

понедельник, 30 ноября 2020 г.

решение проблемы "gulp no tasks found" в visual studio

 Пару раз сталкивался с ситуацией: есть проект Asp.net mvc Core, на нем настроен gulp (компиляция less, минификация CSS и JS и т.п.).

запускаются эти процедуры через Task Runner Explorer. у других разработчиков на проекте с этим проблем нет.

но у меня Task Runner Explorer говорит "no tasks found". и кнопочка "Обновить" не помогает.

Решение проблемы такое:

  1. устанавливаем на компьютер свежий nodejs, убеждаемся, что в консоли (cmd) вызывается именно он ("node --version")
  2. устанавливаем его в качестве основного в Visual Studio:


  3. устанавливаем gulp локально в папку проекта (csproj). для этого:
    1. "cd <папка проекта>"
    2. "npm install gulp-cli"
*установленный глобально gulp Студия не видит, вроде

все, после этого должно заработать. можно на всякий случай Студию перезапустить и в Task Runner Explorer кнопочку "Обновить" понажимать.

после установки gulp у меня были изменены некоторые файлы с json-настройками, касающимися gulp, в проекте. но я все изменения откатил, а gulp-задачи Студия видеть не перестала (т.е., проблема не вернулась)


Visual Studio 2019


вторник, 23 июня 2020 г.

Swagger/OpenAPI - SOAP для REST API


недавно я по работе писал обращение к REST-сервису - так я был , прям, неприятно удивлен: столько мороки! я привык, что, когда работаешь через SOAP/WSDL, указываешь IDEшке URL сервиса, у тебя волшебным образом появляются прокси-классы, просто создаешь экземпляр класса, вызываешь метод - все! 
а тут же все ручками прописывать! всю сериализацию! и классы! а если там POCO с несколькими уровнями вложенности - на C# это вообще ад!
в общем, решил я выяснить, есть ли альтернатива. и, оказалось, есть!
спецификация называется Swagger. или это ее реализация? новое название ее  - OpenAPI. или swagger - просто одна из ее реализаций? есть спецификация, и много реализаций. и называется это все Swagger/OpenAPI.
чтоб оно заработало - нужно вручную прикрутить поддержку Swagger на стороне Rest-сервиса. а потом воспользоваться Swagger-клиентом на уровне Visual Studio.
я читал об этом вот тут:

в этих статьях предлагается 2 подхода, реализующие примерно одно и то же. я для себя решил остановиться на следующем:
  1. для поддержки Swagger на стороне Rest-сервиса меня вполне устроило использование Swashbuckle
  2. если нужен C#-клиент, и не нужно тонкой настройки прокси-классов - можно использовать встроенный в вижуал-студию механизм: Connected Services - Add connected service - Service References (OpenAPI, ...) . ну и там разберетесь.  этот подход хорош тем, что сгенерированные классы появляются в папке "obj". собственно, в качестве исходдика в Git попадает только один JSON-файл со swagger-описанием сервиса
  3. если нужна тонкая настройка прокси-классов или помимо C#-прокси нужны еще и TypeScript-прокси - тогда нам на помощь приходит Unchase OpenAPI. там столько настроек, что аж страшно становится! я все сделал, в основном, по дефолту :)

я изучал вопрос для .net core 3.1, но, думаю, должна быть поддержка и для .net framework

работал на Visual Studio 2019 Community Edition


работающие тестовые приложения есть в моем тестовом репозитории:

ветка Swagger__Swashbuckle - п.1 в списке выше
ветка Swagger_NSwag_Client - п.2 в списке выше
ветка Swagger_UnchaseClient - п.3 в списке выше

ветка Swagger__NSwag_Server - альтернативный способ поддержки Swagger на стороне сервера

вторник, 12 мая 2020 г.

фичи Entity Framework Core, которых нет в Entity Framework 6

кратко изучил новые возможность EF Core. на основе таблицы: https://docs.microsoft.com/en-us/ef/efcore-and-ef6/

есть прям крутые штуки!


  • Constructors with parameters - если конструктор сущности содержит параметры, по имени соответствующие полям-участникам модели - вместо полей значения передаются в параметры конструктора
  • Property value conversions -  можно делать промежуточную конвертацию между значениями в колонках БД и свойствами объекта. к примеру, преобразовывать значения перечислений в строку и хранить в БД в строковом виде. можно делать свои преобразователи, и есть ряд стандартных уже готовых преобразователей. например, преобразователь энама в строку
  • Mapped types with no keys - можно объявлять в контексте сущность на основе БД-View. и потом использовать ее как базу для построения запросов. при какой-то там поддержке со стороны БД дыже будут отслеживаться изменения.
  • Shadow state properties - блин, круть! позволяет к таблицам сущности добавлять дополнительные служебные колонки, которые не нужны в классе сущности / противоречат OOP/DDD (например, LastUpdated, RowVwersion...)
  • Alternate keys - возможность использовать ~осмысленное поле в качестве ключа. и внешние ключи чтоб на него ссылались (или на них)
  • возможность генерировать ключи для новых сущностей на клиенте (в частности, алгоритм hiLo) - для новых сущностей сразу известен их ID, не обязательно сначала сохранять сущность в БД
  • Global query filters - возможность применять фильтр к ~сущностям-таблицам ( https://docs.microsoft.com/en-us/ef/core/querying/filters). к примеру, чтоб в в коллекции context.MyEntities не включались вопросы с флагом IsDeleted = true
  • Field mapping https://docs.microsoft.com/en-us/ef/core/modeling/backing-field?tabs=data-annotations - вроде как, EF - будет писать в приватное поле, а не в свойство, если найдет поле для свойства по конвенции (типа, Url/_url). и читать, наверное, тоже. типа, чтоб не задевать возможную логику, заложенную в геттерах-сеттерах
  • Nullable reference types https://docs.microsoft.com/en-us/ef/core/miscellaneous/nullable-reference-types - я так понял, с nullable reference types в контексте EF Core больше гемора. но не знаю, надо будет на практике опробовать
  • Raw SQL queries: Composing with LINQ https://docs.microsoft.com/en-us/ef/core/querying/raw-sql - ауфф! можно получать коллекцию сущностей  из чистого SQL-запроса, и эту коллекцию можно использовать в построении дальнейших запросов
  • Batching of statements -  https://www.talkingdotnet.com/what-is-batching-of-statement-in-entity-framework-core/ - оказывается, в EF6 , когда выполнялась команда SaveChanges, на каждый создаваемый или изменяемый объект выполнялся отдельный запрос insert или update. в Core изменения по нескольким сущностям выполняются одним запросом
  • Disconnected graph low-level APIs https://www.entityframeworktutorial.net/efcore/working-with-disconnected-entity-graph-ef-core.aspx - улучшена (видимо) возможность сначала создавать графы объектов в памяти, а потом коннектить их к дата-контексту
  • DbContext pooling - https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-2.0#dbcontext-pooling - ну вот, пул контекстов. используется на уровне DI. как я понял, когда вышли из скоупа - все изменения сохраняются (context.savechanges), все EF-поля контекста ресетятся, и контекст кладется  обратно в пул
  • In_Memory DB Provider - для тестов!

понедельник, 4 мая 2020 г.

хранимые процедуры (stored procedures) - стоит ли применять?


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

Вот что я для себя выяснил:

  • СУБД гораздо менее дружелюбны к масштабированию ( https://habr.com/ru/post/487622/, один из комментов)
  • неудобство контроля версий. прям, печаль, люди опытом делятся, какое решение кто нашел. целая буча, в общем
  • скудные возможности языка
  • как следствие из предыдущего - тяжело/не возможно следовать принципам ООП - на мой взгляд, самый тяжкий из грехов
  • проблемы с юнит-тестированием (вытекает из предыдущего) (хотя, другие говорят, что как-то можно)
  • не скейлятся (ну или скейлятся как-то проблемно. типа, они ~"изначально должны быть заточены на шардинг", чтоб их можно было скейлить). это, кстати, чаще других упоминается.
  • тяжелее прописывать сложную логику 
  • IDE для разработки ХП, возможно, будет лажовым (зависит от СУБД)
  • язык хранимок распологает к копипасте 


сам я не использую хранимки, поэтому делал упор на аргументы против :)
про аргументы "за" у меня сложилось впечатление, что большинство их них можно не принимать во внимание при наличии 3-звенной архитектуры / бизнес-слоя / сервиса бизнес-логики. Единственный убедительный для меня аргумент - оптимизация. для себя я сделал вывод, что, как и в случае с другой оптимизацией, хранимые процедуры нужно применять только в "бутылочных горлышках системы". и заплатить за это, как и в случае прочей оптимизации, придется простотой поддерживаемости кода. в общем, без необходимости лучше не использовать.

полезные ссылки: 


суббота, 18 апреля 2020 г.

Visual Studio VS Nugget packages VS Git Submodule

решил недавно проблемку, может, этот текст кому-то сохранит часик времени.

есть .net-приложение, исходники котрого представляют из себя .net-решение (solution), состоящее из проектов

и есть второе, тоже решение/проекты

некоторые из этих проектов используются в обоих приложениях (общие утилиты, общий код), поэтому эти проекты вынесены в git-подмодуль (submodule). в подмодуле они привязаны к другому решению (в смысле, sln-файл лежит тоже в подмодуле. то есть, общие проекты привязаны и к sln в подмодуле, и к sln в родительском проекте )

так вот, недавно понадобилось в один из разделяемых проектов добавить nuget-пакет.
и столкнулись с такой проблемкой: если добавлять nuget-пакет из Вижуал Студии с загруженным родительским решением (в смысле, sln вне подмодуля) - бинарники пакета добавляются в папку packages этого родительского решения. и, соответственно, во втором родительском решении  у общих проектов будут недействительные ссылки на бинарники.

чтоб не сталкиваться с этой проблемой, нужно nuget-пакеты в общий код добавлять из-под решения, находящегося в подмодуле.
но будет небольшое неудобство: после клонирования репозитория и подмодуля в новую папку, чтоб nuget скачал все пакеты для проектов подмодуля через GUI-команду  "Restore nuget packages" , придется загрузить sln из подмодуля и выполнить эту команду так же и там


папки "packages" у нас игнорируются через .gitignore, чтоб не забивать git бинарниками


.net framework 4.7.?, Visual Studio Professional 2017

четверг, 2 апреля 2020 г.

как Linq To Entities соотносится с Entity Framework


  1. EF  - ORM-надстройка над SQL. умеет работать с сущностями, поля которых раскиданы по разным таблицам. имеет свой язык запросов и API. работоспособен и без LINQ.
  2. Есть много разных ~Linq-драйверов. например,  Linq to XML. можно написать свой (пример Linq to Files).
  3. ну и , соответственно, Linq to EF - это драйвер Linq для EF