Comments 201
и не могу это сделать на .Net (привет web.config, который “по сути” тот же web.xml, только еще и перемешанный с конфигом).
Я вот пишу облачные микросервисы в Azure (serverless и webapp) и чот мне ни разу не потребовалось включать web.config в проект. Всё можно из кода настроить. Пишу под netcoreapp2.0
Максимум для удобства быстрой настройки логирования или параметров приложения вообще (connection strings) подключается app.config (который JSON)
Спасибо за комментарий. Сфокусированность микрософта на своем личном облаке это одна из вещей, которая меня очень настораживает в. net core и почему я не очень верю в его будущее (по крайней мере в российских реалиях). Весь кровавый интерпрайз попытались оставить в старом заброшенном .net 4.6+ и всё переписать заново в core где сегодня csproj (xml), завтра json (который project) а потом опять xml (решили все-таки не выкидывать msbuild), зато в entity framework core банально уже n лет нет lazy loading (т. е. оно не Enterprise ready). Для облаков и микросервисов в них .net core возможно действительно вполне себе ок.
Core реально кроссплатформенно (не зря они сделали Linux Subsystem в Win10).
Как связаны .NET Core и WSL?
Возможность тестировать и писать .net core приложения сразу в Linux.Вы же про нативный докер и прочие специфичные инструменты, которые нормально работают только в Linux-окружении? Иначе разрабатывать кроссплатформенное приложение, используя WSL в качестве референса целевой платформы — это выглядит немного странно, как по мне.
И был IIS един и монолитен… да я знаю про Kestrel для .Net Core
Над Kestrel можно и Nginx или IIS в качестве прокси.
Я могу написать web-приложение на Java без единой строчки xml и не могу это сделать на .Net
netcore?
Вот весь xml, который был автосгенерён. Больше трогать его не надо.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" />
</system.webServer>
</configuration>
Есть два основных монстра: EJB и Spring с огромнейшей экосистемой и практиками “вокруг”. В .Net ничего этого нет. Вплоть до выбора нужного DI/IoC-контейнера на вкус разработчика
Очень сомнительный минус, и очень сомнительный плюс.
Кстати, в Visual Studio файлы проектов уже можно писать с нуля руками
Уж пару лет как. Не уверен за самую раннюю версию msbuild, которая может понимать сокращённый *.csproj, но чтобы написать webapp какой-нибудь достаточно пару строчек.
И новые PackageReference руками добавляете?
Ну я вас умоляю, мы ж не в каменном веке. Package Manager'ы же есть.
В .Net есть варианты (перечислю самые, на мой взгляд, популярные):
- Отличный GUI в Rider/Visual Studio (и частично через Command Palette в VS Code)
- dotnet CLI (
dotnet add package Newtonsoft.Json
) - Ручками в csproj (нет подсказок по именам/версиям)
- Nuget Package Manager (CLI / package.config, который ужасен)
- Paket (CLI / paket.dependencies, который прекрасен + есть lock файл с транзитивными зависимостями)
dotnet add package Newtonsoft.Json
Так же есть выбор добавить через GUI от разных IDE: VSC, Rider, VS.
Есть два основных монстра: EJB и Spring с огромнейшей экосистемой и практиками “вокруг”.
EJB — это не фреймворк. Может быть автор хотел сказать Java EE (Jakarta EE). EJB — это всего лишь одна из спек Java EE
EJB это грубо говоря контейнер (я верю что вы это знаете, просто пишу для синхронизации терминологического контекста) и именно альтернативой ему стал в свое время спринг. Это собирательное название для «того что не спринг» и именно эту аббревиатуру обычно не пишут в спринговых вакансиях.
Но концептуально вы правы, наиболее корректно использовать JEE Server (именно эту бирку «лепят» (или лепили?) себе всякие jboss-ы). Или уже правильно Jakarta Server? :)
В .NET выбор очевиден — Visual Studio.Как же Rider?
Для Rider есть достаточно милая инди-лицензия, позволяющая разрабатывать на ней хоть лично для себя, хоть чужой лютый интерпрайз (проблемы совместимости я обнаружил только для некоторых T4-шаблонов, но это специфика).
Это только до тех пор, пока не покупается решарпер.
Я года 3-4 работал с VS Community и ни одной мысли о Pro не возникало — хватало всего что есть. А в Idea Community со спрингом нормально работать невозможно — сделано всё чтобы люди платили деньги.
Я года 3-4 работал с VS Community и ни одной мысли о Pro не возникало — хватало всего что есть.Вы/организация точно не нарушали Community-лицензию при этом? Ведь при желании можно и райдер «покрякать» и считать бесплатным.
А решарпер (который всего на $10 дешевле райдера) вы тоже принципиально не используете?
сделано всё чтобы люди платили деньги.Вы так говорите, будто это что-то плохое. Коммерческая фирма делает качественные инструменты и просит за это деньги! То ли дело MS, которая выпускает эсклюзивную Visual Studio для своей платной операционной системы!
Не нарушал я ничего, речь идет о домашнем компьютере и pet-проектах.Там может каждый делать то, что ему вздумается. Я все же про прямое назнчение инструментов — интерпрайз. MS молодцы, конечно, но у них такие меры — не от лучшей жизни.
Вопрос про решарпер все так же актуален.
А вот в IDEA Community жадинки отрезали использование спринга с бутомВам maven там тоже отрезали?)
Почему тогда у меня проекты на спринг буте прекрасно работают в IDEA Community?
Это утверждение ложноВнезапно. Под Linux тоже версия данной IDE есть?
JetBrains Rider для индивидуалов без решарпера стоит 139$ в год пруфлинк + Linux = 7 942 рубля, Windows 10 Home стоит 5 500 руб пруфлинк + Visual Studio Community = 5 500 руб… и еще решарпер сверху за $129 (=
МС с удовольствием сделали бы версию под Линукс, но пока не могут — слишком долго портировать такого монстра.
Очевидно, что если бы MS не сделало бесплатной студию, то с таким подходом рынок они бы потеряли уже в обозримом будущем.
он может стать основным продуктом из семейства Visual Studio
Но он не станет Visual Studio (= Начало конца уже положено в его технологических основах.
Да, я знаю про jOOQ, но ни разу не видел его использование хоть в чем-то, напоминающем продакшен. Возможно потому что это полу-платный новодел без JSR, возможно по другой причине.
В защиту jOOQ'а скажу, что во всю используем в продакшене энтерпрайза: гораздо очевиднее, чем JPQL/Criteria Builder, а в сочетании с правильной готовкой миграций даёт управляемую работу с БД. Почему-то JPQL/Criteria Builder считают, что разработчики не могут в SQL, поэтому предлагают навернуть абстракций там, где можно обойтись понятным и проверяем (во время компиляции) кодом.
На многих проектах контейнеры вообще не используются, даже в 2018 году (да, на это больно смотреть, но я это наблюдал и ни раз).
Контейнеры головного мозга
Да и тенденции в мире также смотрят в сторону .Net ...
Это какие например?
C# куда как продуктивнее Java.
А что под этим подразумевается, можно поподробнее?
… к продуктивности программиста? Я не соглашусь, дженерики сильно на это влияют, expression trees — тоже.
Последний раз я их ковырял когда правил форк от ORM и больше «с ходу» не припомню необходимости.
Про дженерики тоже холиварный вопрос, в джаве они есть, причем с неплохой ковариантностью-контрвариантностью из коробки, ala
List<? extends A> myList1
List<? super B> myList2
Ну да, type erasure. Сейчас минусаторы набегут, но в большинстве повседневных задачах он не мешает.
Мы же про продуктивность? Почему не вспоминаем про тот же Lombok
@NonNull
@AllArgsConstructor
@ToString
@EqualsAndHashCode
Getter/@Setter
Вот это про продуктивность. И никакого бойлерплейта.
В дотнете такое возможно огромными костылями ala Postsharp (который почти загнулся из-за платности / заметно возрастающего времени компиляции), ну или Fody (который тоже не оч.популярен). Появилось ли что-то похожее в .Core?
Можете мне привести пример частого использования expression trees в кровавом энтерпрайзе?Составление фильтров.
Можете мне привести пример частого использования expression trees в кровавом энтерпрайзе?
LINQ, AutoMapper, FluentAssertions. Мы вот у себя только что маленький внутренний движок критериев на expression tree сделали.
Почему не вспоминаем про тот же Lombok
Это не к мне вопрос, я всего лишь показываю, что пункты из списка имеют отношение к продуктивности.
Да и-то в качестве «запросов к БД» или куда-либо ещё.
Что автомаппер что FluentAssertions, что Linq2Objects на простых лямдах достаточно нормально отжимаются.
Разве что LINQ принимается
Вы просили пример использования — вы их получили. То, что это можно сделать иначе — понятное дело; но это не значит, что иначе сделать удобнее.
Что автомаппер что FluentAssertions, что Linq2Objects на простых лямдах достаточно нормально отжимаются.
И как вы из простой лямбды получите описание провалившегося assertion?
Плюс если вспомнить любимого Рихтера, то он ненавидит проперти со времен первого издания своей книги про CLR и говорит что стоит явно писать методы, которые не несут «многозначности то-ли переменная то ли метод» :D
Но это я уже подтроливаю немножко, да. Еще Рихтер везде sealed рекомендовал, помнится.
Что характерно, вопросов, причем тут котлин, не возникало.
Хоспадя, причем здесь F#
Я сам из тех, которые на F# лепят.
Он очень даже при том.
Получаете кучу бонусов в языке, синтаксисе, системе типов, но теряете немного в IDE (Visual Studio днищенски поддерживает F#, VS Code — норм, Rider EAP 2018.1 уже тоже норм), в тулах (нет ничего подобного R#, но учитывая что язык гораздо менее бойлерплейтный и защищает от ошибок намного сильнее, надобность уже не та. Так же нет нормальных декомпиляторов, если dotPeek'ом тыкаться, получаем бесплатную обфускацию)
А главное dll те же, dotnet xxx.dll
всё так же работает, поэтому хоть в Azure, хоть в AWS Lambda заливается абсолютно одинаково.
Ну и если чо, компилятор и темплейты проектов F# в .NetCore SDK уже встроены.
Поэтому встречный вопрос:
А почему не F#?
Почему не вспоминаем про тот же Lombok
Потому что инструменты с вплетением байт-кода есть и для дотнета: от Fody до PostSharp.
Для NotNull в дотнете хватает системы типов (благодаря тем самым, не имеющим отношения к вашей личной продуктивности, генерикам и структурам): я, например, просто могу писать NotNull<T> и это будет та же самая ссылка на класс без оверхеда, но с гарантией, что null там нет.
с неплохой ковариантностью-контрвариантностью из коробки
Согласно Джону Скиту, это единственное преимущество языка Java над C#.
в большинстве повседневных задачах он не мешает
Ну да, конечно. Если я в параметре конструктора укажу IEnumerable<TypeName>, то дотнетные контейнеры автоматически подставят мне все зарегистрированные реализации для TypeName.
В яве это не сработает по построению. Именно поэтому явовские контейнеры на фоне дотнетных смотрятся убого.
Если потребуется оптимизация по аллокации памяти в куче, в яве придется делать специальные алгоритмы с использованием только примитивных типов.
Getter/@Setter
В дотнете для этого костыли не нужны — все уже есть прямо в языке.
Но то что большинство текущих проектов на .NET (не Core) внезапно стало Legacy — это факт.
В .Net ничего этого нет. Зато есть изобретение велосипедов “в каждом проекте по-своему”. Вплоть до выбора нужного DI/IoC-контейнера на вкус разработчика (если разработчик вообще в курсе про существование контейнеров) и решение как управлять транзакциями (если разработчик опять же знает, что такое транзакции и кто-то догадался отключить автокоммит на Sql Server-е). Разве что ASP.NET MVC немного похож на Spring MVC (который лишь малая часть Spring Framework).
.Net Core принес встроенный DI, который покрывает 95% нужд. И что вообще плохого в выборе DI/IoC-контейнера самостоятельно из существующих? Лучше иметь одну прибитую гвоздями реализацию?
Про транзакции немного не понял, их управление строится через конфигурацию ORM, как и в мире Java. Или речь о распределенных?
Опять-таки .Net Core предлагает многое, из того, что есть в Spring Framework (если, конечно, описание его состава на википедии не врет). Не все, но многое. Остальные вещи можно найти, установить и «подружить».
И был IIS един и монолитен. И поняли Микрософт, что System.Web это плохо. И придумали OWIN.
OWIN дал возможность более гибко и прозрачно конфигурировать пайплайн http-запроса через middleware.
В общем, на вкус и цвет — фломастеры разные.
Транзакции — скорее про аннотацию @Transactional.
OWIN еще и Embended Server дает. Еще немного, и Микрософт придумают свой H2 (или уже придумали?).
в одном проекте Unity, в другом — Autofac, в третьем StructureMap, а в четвертом NInject — и все они различаются в API и при этом одинаковые на 95%. Здесь огромный плюс джавовских JSR виден, надеюсь, всем.
В том же ASP.NET MVC адаптируются в
IDependencyResolver
.В том же ASP.NET MVC адаптируются в IDependencyResolver.
Опускаясь на уровень этого интерфейса все эти контейнеры полностью теряют уникальные фичи (Ninject — auto discovery, SimpleNinject — проверку на собираемость и т.д.) что делает наличие такого большого кол-ва реализации контейнеров бессмысленным.
Если для в вашем проекте контейнер лезет куда-то еще, значит ваша команда не осилила DI.
Аннотации — магия из каменного века и антипаттерн.
Явовские контейнеры после дотнетных ужасны.
Точка сборки — это к Кастанеде Карлосу ;)
Явовские контейнеры можно конфигурировать кучей способов (сходу назову штук 5), при этом бут добавляет удобную авто-конфигурацию «из коробки». Не будьте столь категоричны, это неконструктивно и неприятно читать.
1) IntelliJ лучше чем Visual Studio. Хотя VS+ReSharper стирает все преимущества IntelliJ, но всё же ReSharper добавляет свои проблемы (не знаю исправили баг или нет, но RS очень не любит WPF и в нашем проекте, плагин для VS, у нас почти все xaml.cs файлы были красные из-за того, что он не видел зависимости или что-то в этом роде), IntelliJ свои баги, тоже есть, но всё же для меня IntelliJ было приятным открытием
2) Очень неудобная настройка билдов (maven). Кроме того, что это огромные файлы xml, так в той же intellij нет(либо я не нашёл) GUI для управлением этим файлом и чтения зависимостей. Gradle почти тоже самое, правда все же файлы не такие огромные
3) Как же плохо без дефолтных фреймворков. Что я имею ввиду — огромное количество разных orm, библиотек логирования и т.д. Кому-то это плюс но в корпо это ужас ибо работаешь с разными программистами, с разных стран, у всех свои стандарты и пожелания. В итоге в проекте у нас 3 библиотеки для логов, ибо каждый вбил что хотел в свое время, используется MyBatis который конечно быстрый, но неудобный и вообще Spring Boot сейчас уничтожает все апгрейды у нас в проекте, потому что у нас Spring 3, сделали апдейт до 4, а дальше уже тяжело, ибо нужны новые версии зависимых других библиотек, а они все почти уже имеют настройки под Spring Boot. Ясно, что можно и под обычный настроить Spring, но если нет документации, то на это уходит много времени. Как пример — сейчас нам надо сделать Gateway и мы такие обрадовались, ведь в Spring Cloud появился как раз Gateway. Только фигушки нам ибо зависимости идут на Spring Boot и нет ещё статей на тему как поставить это на обычный Spring. К тому же очень мало статей на тему hello world в spring security на обычный spring. Найти конечно можно, но всё равно большинство под Spring Boot. В итоге сейчас думаем, что надо переноситься на Spring Boot 2, но у нас там столько зависимостей и не факт что все они имеют апдейт до SB2 и Spring 5. Вообщем ад и в .net даже близко такого не было никогда. В .net уже очень давно есть WCF и IIS, которые бы решили нашу проблему
4) Закончу на положительной ноте для Java — open source. В той же IntelliJ можно найти имплементацию любого метода и даже в дебаг кинуть. В .net core была подобная возможность, дебажить исходники, но потом почему то убрали и сделали фигню, которая работает только в call stack, а вот если просто нажму open implementation на системном методе, то мне покажет только методанные. Вообщем огромный плюс Java
Если я в чем-то не прав то пожалуйста напишите об этом, буду рад любой информации
rider нынче позволяте дебажить чужие исходники
В своё время со spring security здорово помог разобраться цикл статей отсюда. Они актуальны и для 4-го спринга: http://krams915.blogspot.com/search/label/Security?m=1
Очень неудобная настройка билдов (maven)
В idea есть maven plugin, который позволяет удобно выполнять частые операции с maven, поддерживает профили и т.д. Файлы xml maven хоть и часто большие, но однообразные и простые по структуре. Это отличается от xml в мире .net, где из-за сложности пришлось сделать графическую утилиту. Как правило в pom копируется зависимость и забывается, idea же при редактировании подсказывает синтаксис и проверяет ошибки.
Как же плохо без дефолтных фреймворков
Вам в помощь Spring Initializr (https://start.spring.io/). Выбрали нужный функционал, который нужен в проекте, нажали Generate и уаля у вас на выходе проект, который сразу запускается и содержит все что нужно.
Это отличается от xml в мире .net, где из-за сложности пришлось сделать графическую утилиту.
У вас устаревшие сведения. cproj нового образца и маленькие, и простые.
Я пользуюсь и тем и другим — смотря что удобнее по ситуации.
Так что у дотнета преимущество в обоих случаях.
Так что у дотнета преимущество в обоих случаях.
Не у дотнета, а у одной конкретной IDE (VS) над другой конкретной IDE (Idea) в конкретном вопросе (GUI для редактирования конфигов). Да и то преимущество спорное, на любителя.
Именно что у дотнета.
- Новый формат cproj — это все тот же msbuild (а не ide), замены которому де-факто нет.
- "Конкретная IDE" является лучшей и господствуещей на рынке разработки для платформы.
- Инструменты для явы почему-то никто от самой явы не отделяет — логично и с дотнетовскими поступать так же.
Да, я знаю про jOOQ, но ни разу не видел его использование хоть в чем-то, напоминающем продакшен.
Есть Querydsl, использовал в продакшене и не могу нарадоваться. Ещё есть Jinq, но с ним я только игрался и идея использовать его в продакшене мне кажется сомнительной. Причина — использует сериализуемые лябмды, что накладывает множество ограничений (лучше анализировал байт-код лябмд с помощью какого-нибудь инструментатора/класслоадера).
Возможно потому что это полу-платный новодел без JSR, возможно по другой причине.
JSR не панацея. На спринг есть JSR? А, скажем, для логгирования используют log4j/logback/slf4j вместо стандартного (JSR) java.util.logging.
Работал с asp еще до того как был .net, потом с monorail, потом с asp.net mvc и asp.net core, тоже недавно перешел проект, где один из сервисов на Java и spring boot, остальные C# asp.net core.
Впечатления в радикально отличаются от впечатлений автора:
VisualStudio vs Idea
- VS (даже с R#) гораздо стабильнее и быстрее чем idea, по крайней мере на моих маленьких проектах
- в VS не нужна кнопка invalidate caches and restart, за много лет использовал сброс кеша R# один или два раза, в idea при переключении веток и редактировании зависимостей gradle регулярно ее использую
при переходе С# => Java очень напрягает:
- отсутствие var, async/await, linq, extension methods и class properties
- местами очень недружелюбный api библиотек
- type erasure, не предполагал что так быстро с ним столкнусь
- checked exceptions, не ощутил пока особой пользы
при переходе asp.net => spring boot:
- аннотации везде и для всего, причем не везде даже с compile time checking
- неявный DI, аннотации для регистрации
- отсутствие nuget install-package и UI к нему
не могу согласиться с:
Впрочем, адекватные альтернативы IIS под Windows от этого не появились (да я знаю про Kestrel для .Net Core).
selfhosted asp.net webapi можно было писать и до .net core, хочешь запускай как консольное приложение, хочешь как win service с TopShelf например, отличный вариант для новых приложений который не зависят от возможностей IIS
Только спустя 15 лет в Микрософт поняли, что это хорошо и пора перестать диктовать миру “как правильно жить”
у меня сложилось впечатление что это в spring boot мне диктуют как правильно жить, как иcпользовать DI, как называть разные lifescope и тд
Я могу написать web-приложение на Java без единой строчки xml (привет Spring Boot), и не могу это сделать на .Net (привет web.config, который “по сути” тот же web.xml, только еще и перемешанный с конфигом).
пара очень простых и легко читаемых файлов в проекте напрягают гораздо меньше чем gradle config, хотя он и не xml
у меня сложилось впечатление что это в spring boot мне диктуют как правильно жить, как иcпользовать DI, как называть разные lifescope и тд
Так никто же не заставляет использовать Spring Boot, тем более на него нет JSR. Можете использовать любой другой фреймворк, коих довольно много. И это отличается от ситуации с .net, который до недавнего времени был закрытым и фактически был прибит гвоздями к Windows (энтузиасты из Mono не в счет). И хорошо, что сейчас все по другому, но почему бы не сделать этого раньше?
Подобное в JVM без костылей не сделать:
class Foo: IProcessor<A>, IProcessor<B> {
void Exec(A arg){
...
}
void Exec(B arg){
...
}
}
т.к. во время компиляции void Exec(A arg) и void Exec(B arg) превратятся в void Exec(Object arg) и мы получаем конфликт между двумя методами с одинаковой сигнатурой. Можно создать явно интерфейсы IProcessorA и IProcessorB в которых будет указана сигнатура, не имеющая generic type аргументов, но этот workaround мешает компоновке библиотек, т.к. появляется зависимость на конкретный интерфейс для конкретного аргумента generic типа (IProcessorA — A). А это значит, что все, кто захотят поддерживать интерфейс IProcessor, должны заранее договориться использовать общую сборку в которой лежит IProcessorA. А теперь представим, что есть N независимых разработчиков, не знающих друг о друге, объявивших в своих библиотеках свой IProcessorA…Есть решение через полиморфизм, но это в свою очередь осложняет жизнь тем, что в каком-то месте вам нужно указать все поддерживаемые типы-наследники. Что также является антипатерном. В общем, из одной ловушки в другую.
Подробнее тут.
Можно привыкнуть к новой IDE, освоить новый язык, потратить многие месяцы на изучение нового технологического стека, но один лишь факт того, что в языке нет полноценной реализации такой базовой штуки как Generic Types, означает, что постоянно будет ощущение неполноценности разрабатываемого кода, по сравнению с аналогичной реализацией на .Net.
Пробовал программировать на Kotlin (на мой взгляд, у языка прекрасный синтаксис), но описанная выше проблема сводит его преимущества перед C# на нет.
постоянно будет ощущение неполноценности разрабатываемого кода
Это не просто ощущения, а суровая реальность.
Контейнеры в яве такие страшные (с засилием аннотаций) как раз из-за генериков.
Нормальных коллекций для типов-значений нет тоже из-за генериков.
Даже если введут кастомные типы-значения толку от них будет мало опять-таки из-за генериков.
Все преимущества в производительности от шикарного оптимизирующего рантайма могут быть сведены на нет теми же генериками.
По ходу автор просто нашел себе нового идола для карго-культа.
В .NET выбор очевиден — Visual Studio.
Как же VS Code для .net core? Rider?
Главное преимущество лямбд — типизируемость. Кто-то использует дапперы и фигачат всё на SQL, только вот гарантировать правильные типы, увы, становится невозможно.
Любой код самодокументируемый
Очевидно, нет.
потому что иначе оно бы не работало.
Для того, чтобы код работал, читаемость не обязательна.
1) SQL-образный
var selectedUsers = from user in users
from lang in user.Languages
where user.Age < 28
where lang == "английский"
select user;
2) С использованием лямбд
var selectedUsers = users.SelectMany(u => u.Languages,
(u, l) => new { User = u, Lang = l })
.Where(u => u.Lang == "английский" && u.User.Age < 28)
.Select(u=>u.User);
Причём запросы могут формироваться, как LINQ for Objects, так и LINQ for Entities. Первое — для коллекций, второе — для ORM, что в итоге преобразуется в банальный SQL запрос для СУБД.
И то и то LINQ, просто у него 2 формы записи: query linq и method chain linq. Первый вариант иногда читаемее, а иногда нет. Например типичный запрос выглядит так:
var foo = mytable.Where(x => x.Foo == 1).Select(x =>x.Bar).FirstOrDefault()
В виде query получается немного нелепо.
А я изначально подумал что вы в прямом смысле про SQL в шарпе:
var foo = mytable.Query<Thing>("select * from Thing where Name = @Name", new {Name = "abcde" });
Насколько это читаемее — вопрос
Джава очень уж многословна по сравнению с шарпом. В нее автопроперти-то завезли наконец?
геттеры и сеттеры генерятся легко в любой IDE
Претензия не в том, что геттеры/сеттеры сложно генерировать, а в том, что по сравнению с .Net наблюдается увеличение объёма кода. Вместо одной сущности — автосвойства, три — переменная + геттер + сеттер.
Гоферы с тем же успехом ссылаются на прости господи кодогенерацию.
В дотнете Fody тоже никого не смущает.
Но никто не делает вид, что вплетение кода заменяет имеющиеся языковые средства задаром.
А котлин мне очень нравится.
Но, возможно, сейчас и тут напишут про проблему с дженериками.
Такова жизнь. В JVM JIT и сборщик мусора лучше дотнетных. Но нет генериков и непримитивных типов-значений.
PnP в конечном итоге извергло из себя Unity (не движок для игр, а контейнер), которое преподносилось в ~2010 как супер ноу-хау в т.ч. в живых семинарах в Мск. Это было как минимум забавно — ничего нового, но пафоса горы.
1. В .NET нет нормальной платформы для разработки ентерпрайз приложений.
2. 15 лет микрософт «в одно рыло» делал изменения в языке и .NET Framework.
И-то и то верно, вы с этим спорите что ли?
В .NET нет нормальной платформы для разработки ентерпрайз приложений.
Define "нормальная платформа".
Конструктивней в данном треде, увы, вряд ли получится, здесь какая-то атмосфера нездоровая — сплошные переходы на личности с двоемыслиями, define и т.д. Неинтересно.
А если посмотреть на спринг.клауд, projects.spring.io/spring-cloud то его фичи это вообще космос, вообще не знаю ничего похожего для .NET.
Один фреймворк для всего?
Спасибо, не надо.
Вдобавок у комментатора с опытом здесь же https://habrahabr.ru/post/352404/#comment_10732666
мнение про Spring слегка отличается от вашего.
В .NET есть аналоги, но не прижились они.
Как не прижились?
Fody жив-здоров, чего и вам желает.
PostSharp на этом вообще деньги зарабатывает.
Ну и масса библиотек над Castle.DynamicProxy
А к примеру в том же спринге в разделе про Data — с этого всё начинается docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html
Я сам прошёл путь от оголтелого отрицания «платформ» до понятия их необходимости в корпоративной среде. Позволяет не ходить по одним и тем же граблям разными путями в разных проектах.
Вы на редкость самокритичны.
Это не определение. Если вы хотите сказать, что ничто кроме Spring — не нормальная "платформа для ентерпрайз приложений", то… ну ок, чо. Пойду писать свои ентерпрайз приложения без платформы.
2. Как будто что-то плохое: в яве очень много сделано в стиле «лебедь щуку раком», когда на каждый чих есть 100500 разных несовместимым между собой библиотек со своими уникальными недостатками.
И на OData доводилось писать когда не было никаких GraphQL. И только версия OData 4.0 уже хоть как-то подходила для продакшн, хотя и приходилось всё равно вставлять кучу костылей.
Вы как-то в одни ворота играете… :)
Давайте вспомним, например, (N)Hibernate. В каком году микрософт задумалась об ОРМ? А DI/IOC-контейнер в каком году появился? А библиотеки модульного тестирования ala N(J)Unit откуда портировались?
Я согласен, что синтаксис и возможности языка C# приятней (микрософт переосмыслил ошибки Java, это известный факт). Но что касается экосистемы вокруг — здесь Java действительно впереди, как бы я не любил C#.
И .NET Core это попытка MS запрыгнуть в уходящий поезд (возможно что-то и получится).
Кстати, Java тоже решила ускориться и перешла на полугодичный цикл релизов.
Так что дальше будет еще интересней. А то что языки черпают друг у друга новые возможности — это же хорошо.
К версии 4 оно всё-такие мигрировало на более адекватный и гибкий Web Api.
Потом, впрочем, и Web Api канул в лету (оно и к лучшему).
Никто уже не помнит WCF Dataservices? Это и была одна из причин провала OData-ы — прибитая гвоздями кривейшая концепция и инфраструктура.
Вы под провалом OData понимаете то, что у нас до сих пор ощутимый поток интеграций через этот интерфейс?
Потом, впрочем, и Web Api канул в лету (оно и к лучшему).
Ыыы, а на чем я пишу сейчас?
Под провалом odata я понимаю что практически никто за пределом .net песочницы о ней не слышал, хотя технологии ~10 лет (да и в песочнице она нечасто всплывает)
Пишете на WebApi? А как же .Core которому здесь сотню комментариев подряд все оды поют?
Пишете на WebApi? А как же .Core которому здесь сотню комментариев подряд все оды поют?
Так это оно и есть.
Оно ж с MVC слилось в экстазе когда ms осознал что две параллельные реализации контроллеров и инфраструктуры вокруг них не есть хорошо. М?
Оно ж с MVC слилось в экстазе когда ms осознал что две параллельные реализации контроллеров и инфраструктуры вокруг них не есть хорошо. М?
ну да слилось, это плохо? Старые MVC неймспейсы убрали (System.Web.Mvc
стал Microsoft.AspNetCore.Mvc
), унифицировали работу с контроллерами, но в целом это тот же самый старый добрый WebApi.
Живее всех живых короче.
Всё что можно было делать в Web Api, можно было делать и в MVC через JsonResult метода контроллера. Разве что без OWIN и Embeded Server и чуть более «многословно».
Так что Web Api попросту умер, когда в новом «более лучшем» MVC пришлось/удалось отказаться от System.Web за счет кросс-платформенности. Мавр сделал свое дело, мавр может уходить.
Всё что можно было делать в Web Api, можно было делать и в MVC через JsonResult метода контроллера.
Серьезно? Content negotiation — тоже? Из коробки?
Вот даже видюшку нашёл, харизматичный мужичок был www.techdays.ru/videos/3883.html
Под провалом odata я понимаю что практически никто за пределом .net песочницы о ней не слышал, хотя технологии ~10 лет (да и в песочнице она нечасто всплывает)
Берем, значит, любимый аналитический инструмент офисного работника — я про Excel — и видим там Get Data for OData feed.
Пишете на WebApi? А как же .Core которому здесь сотню комментариев подряд все оды поют?
У нас проект на .net framework. Когда поедем на Core — там все равно схожий движок, так что конкретно в этом месте я ожидаю тривиальную миграцию. Это вам не с WCF переписывать.
- Солюшен всегда был солюшен. Проекты пытались переделать на project.json, но не заехало + я работал с кором начиная с beta4 (в продакшне) — так вот изначальной кор это ад. У JSON нет никакой схемы, ничего не понятно, документации кот наплакал, периодически все перестает работать, где искать ответы — хз. По сравнению с этим расширение существующего XML выглядит как верх читаемости и удобства. JSON ради JSON'а это очень круто, но я на практике видел оба варианта. Не считая того, что я буквально вчера писал свой кастомный таргет для csproj, который через 30 минут после моей идеи о нем был реализован. Потому что не стали городить свой велосипед и просто убрали бойлерплейт, привнеся пользу причем и обычным проектам, ибо новый формат обратно совместим с полным фреймворком.
- Первый раз слышу, чтобы пытались собрать чем-то другим. Первый вопрос — зачем? Ведь в итоге все равно все выльется в msbuild, никто в здравом уме не будет писать свою обертку над csc. Сюда можно как раз вспомнить то, что я написал в предыдущем пункте, я когда писал свой таргет смотрел на стандартные, там СТОЛЬКО логики, что дублировать её можно, конечно, но смысл? Это очень дорогой эффорт, профит от которого неясен — msbuild вполне хорош, если не считать транзитивных зависимостей.
Насчет разных версий msbuild'а было бы интересно послушать, потому что у меня например никогда проблем не было, включая сборку какого-нибудь солюшена под 2010 студию последним компилятором.
Ну а что касается cake — я очень подозрительно отношусь к словосочетаниям "скрипты", "make" и "сборочная система". Ибо навевает печальные воспоминания как я пробовал opencv собрать правильно. Хотя кроссплатформа выглядит заманчиво, не спорю, но разрабатывать на шарпе я бы все равно иначе как на винде не стал бы — все-таки студия пока вне конкуренции. Через пару-тройку лет мб можно будет посмотреть на райдер, но пока в нем много чего не хватает. - Не вижу, чем свобода выбора плоха. Если у вас разработчики не умеют договариваться, то тогда наверное да, диктатура со стороны языка вам на пользу. В моей практике наоборот, возможность выбрать тонко инструмент под задачу позволяет писать намного более приятный код. Нужен простенький DI? Не вопрос, берем Microsoft.Extensions. Нужно что-то посложнее? Окей, берем Autofac. Нужно, чтобы ASP.Net использовал Autofac вместо встроенного DI? Для этого тоже есть пакет. Ну и про "велосипеды на каждом углу" хотелось бы подробнее. Что именно люди переизобретают? В вашем десятилетнем стаже наверняка найдется пара-тройка примеров.
- Как я выше сказал, множество вариантов это всегда хорошо. С другой стороны, у вас ведь разработчики, которые не могут договориться, как же вы можете ставить это как плюс? А вдруг один возьмет servlet api, а другой — tomcat?
- Тут все верно, коммьюнити недавно появилось в процессах. Правда, как мне кажется язык и без того развивался быстрее и эффективнее, а с появлением коммьюнити это впечатление только усиливается.
- Тоже нечего добавить
- А вот тут поподробнее. Я, конечно, извиняюсь, но XML конфиги я уже года 2 точно не видел. Для настроек есть appsettings.json, который удобно подсасывается. Покажите, где тут хоть строчка с XML
Хотел вкратце ответить — но как-то не срослось, решил подробнее остановиться на каждом из пунктов, очнулся уже в конце простыни.
Мое мнение, что на новых языках писать всегда удобнее, чем на старых. Поэтому джава удобнее плюсов, шарп — джавы, а раст — шарпа. С другой стороны, количество библиотек — обратная зависимость. В итоге для меня лично сейчас компромиссная точка — шарп, у которого библиотек меньше чем у любого из этих языков, за исключением конечно раста, но появившийся позже плюсов и джавы и сумевший проделать работу над ошибками. По сути шарп можно считать Java++ с потерей обратной совместимости. Но с ростом количества библиотек у этого самого раста я планирую перейти на него как на основной язык в течение нескольких лет. И не потому, что я люблю системное программирование или производительность, а потому что я на него смотрю высокоуровнево, и для меня отсутствие null в языке это одна-единственная возможность, ради которой можно многое простить. Не считая того, что раст развивается даже быстрее шарпа, причем скорость развития даже сравнивать страшно, 6-недельные циклы против годового, и через эти самые пару-тройку лет там появятся и более крутые вещи — я например очень хотел бы увидеть HKT. В шарпе есть пропозал, но когда его примут — неизвестно. Ну а в джаве я не ожидаю их вообще никогда.
У джавы наверняка есть свои плюсы. Но для меня они заканчиваются на ничего не значащем сахаре вроде "анонимный тип реализующий интерфейс", в то время как отсутствует критически важный функционал вроде дженериков.
У джавы наверняка есть свои плюсы
Java сильна точно не языком. В первую очередь обратной совместимостью и аккуратным подходом к нововведениям. И это очень ценят в бизнесе, но как следствие — медленное развитие и постоянное отставание по фичам. Кроме этого, у джавы мощная инфраструктура и наличие открытых библиотек на все случаи жизни.
Если не нравится Java именно как язык, то можно посмотреть в сторону Котлина. Получите современный язык, который стремительно развивается + из коробки все наследие Java.
Кстати, подумалось, что свеженький Kotlin-то бегает на JRE, а не на CLR…
Кстати, подумалось, что свеженький Kotlin-то бегает на JRE, а не на CLR…
Ну это логично. Его разрабатывает JetBrains, которые свои инструменты исторически пишут на Java. Но Java как язык их не очень устраивает своей архаичностью, а Scala своей загонностью (как альтернатива), решили сделать свой, с фирменным тулингом.
По поводу CLR, по моему, Андрей Бреслав говорил что CLR не выбрали потому, что смысла нет. C# по возможностям близок Котлину, т.е. Котлин если и лучше в чем-то, то не настолько чтобы люди захотели на него пересаживаться. Поэтому выбрали JVM и JavaScript как платформы для старта.
огда наш гипотетический Блаб-программист смотрит вниз на континуум мощности языков, он знает, что смотрит вниз. Менее мощные, чем Блаб, языки явно менее мощны, так как в них нет некой особенности, к которой привык программист. Но когда он смотрит в другом направлении, вверх, он не осознает, что смотрит вверх. То, что он видит, — это просто «странные» языки. Возможно, он считает их одинаковыми с Блабом по мощности, но со всяческими сложными штучками. Блаба для нашего программиста вполне достаточно, так как он думает на Блабе.
DI от явовских генериков страдает очень сильно.
Оптимизация аллокаций в куче — еще сильнее.
Первое — хлеб любых приложений от среднего размера.
Второе — очень больная тема в нагруженных приложениях..
DI от явовских генериков страдает очень сильно.
Искренне хочется расшифровки или пример «сильного страдания»
Искренне хочется расшифровки или пример «сильного страдания»
Практически все функции по ссылке явовские контейнеры не потянут без дополнительных костылей, так как параметры-типы у генериков Lazy, Func, Owned, IList и т.д. после компиляции даже не превратятся в тыкву, а просто исчезнут. На практике я использовал большую часть списка хотя бы однажды, а самые ходовые варианты (Func) — ежедневно
http://autofaccn.readthedocs.io/en/latest/resolve/relationships.html#supported-relationship-types
Почему-то первыми ругать жаву за стирание типов набегают те кто понятия не имеет что именно стирается.
Микрософт за это время успел выкинуть старый .NET.
1. Про дженерики выше много написано.
2. Как связаны Reactive Streams с серверами приложений? В .net Reactive Streams тоже есть (и, кажется, уже везде есть) и сам исходный паттерн Observable встроен в сам язык с самых первых версий.
3. После знакомства с maven и gradle я начал очень сильно ценить и любить msbuild.
4. Доминирования прикладных фреймворков не наблюдаю. Наблюдаю бардак в базовых АПИ (даты, коллекции, etc) и монстроидальные монолитные EE и Spring.
5. В java есть osgi и новый jigsaw. В .net есть MEF, но я ни разу не видел, чтобы кто-то им пользовался.
6. Наблюдаю использование большого количества бойлерплейтных паттернов типа Builder, вместо которых в C# удобный синтаксический сахар.
7. В java очень любят и активно используют annotation processors для генерации кода. После .net ощущается очень свежо и интересно. Dagger удивил, например (а что, так можно было?)
Так же перешел на java после десятка лет на .net.
А какова причина перехода, если не секрет?
В .NET тоже есть определенный бардак в базовом API — в тех же коллекциях и датах.
Насчет коллекций — мое любимое:
А вот почему практически во всех проектах разработчики используют в открытых контрактах своих API либо List(T) (ай-ай, реализация, а не интерфейс, и при этом наиболее "полная" реализация — а как же SOLID?) либо IEnumerable(T) (ай-ай, сколько раз приходилось видеть вызов метода Count())?
Хотя в большинстве случаев по смыслу подходит использование IReadOnlyList(T) или IReadOnlyCollection(T) (список с конечным количеством элементов — упорядоченный по индексу, либо нет).
Если разобраться, то на это разработчиков провоцирует устройство базовых типов самой платформы:
Тип List(T) реализует интерфейсы IList(T) и IReadOnlyList(T).
Но что будет, если одна функция возвратила экземпляр IList(T), который мы хотим передать в функцию, которая на входе требует IReadOnlyList(T) или IReadOnlyCollection(T)?
Правильно — ошибка компиляции, т.к. интерфейс IList(T) не реализует интерфейс IReadOnlyList(T).
Вот и получается, что, чтобы работало, везде лепят List(T).
А вот если вторая функция на входе требует IEnumerable(T), то подойдет любая коллекция, в т.к. IList(T).
Кроме того, использование IEnumerable(T) провоцируется стандартной библиотекой платформы, хотя в большинстве случаев по смыслу речь идет о коллекции с конечным и известных количеством элементов (а что, если в будущем коду самой функции потребуется проверка коллекции на количество элементов? — а ведь замена типа параметра на IReadOnlyCollection(T) приведет к поломке компиляции всего написанного с ипользованием этой функции кода).
Та же проблема касается и словарей — Dictionary(K,V), IDictionary(K,V), IReadOnlyDictionary(K,V).
Получается, при казалось бы, такой сильной реализации Interface Segregation Principle в системе базовых коллекций, из-за такой мелочи по факту этот принцип не используется в прикладном коде.
И еще определенную путаницу вносит наличие ReadOnly- и Immutable-версий коллекций (да, мы знаем, чем они отличаются).
Последние так и не начали использоваться в проектах (у кого-то есть реальные примеры?), а еще перечень Immutable-коллекций не полностью соответствует 1-в-1 набору обычных (что-то добавлено, что-то отсутствует).
По теме статьи — статья как будто хочет сказать, что после знакомства с Java — в .NET все оказывается не так плохо.
Но что по поводу проектов на рынке?
На .NET по-прежнему их меньше чуть ли не в разы, и в основном легаси.
Кое-что появляется на .NET Core, но именно что «появляется», и с качеством кодинга и архитектурой в проектах проблемы (унаследованные подходы или криво применяемые новые).
Т.е., несмотря на тенденции последних лет — развитие C# (6.0-7.x + C# 8 в черновике), взросление F#, появление .NET Core, модульности, новой экосистемы, до сих пор сохраняется неясность по поводу настоящего и будущего платформы.
И еще кое-что.
Изначально .NET затачивался под декстоп и UI, потом плавно перешел на back-end, а с появлением .NET Core стал практически полностью полноценной зрелой back-end платформой.
Но из-за соображений обратной совместимости функции работы со строками (преобразование чисел и дат в строку и обратно и большинство других методов со строками) в большинстве своем работают в текущей культуре, а не в инвариантной или Ordinal-режиме.
В итоге получается, что в бек-енд приложении работа по записи/парсингу какого-нибудь XML, передеваемого между частями системы, превращается в сущий ад, ибо разработчики не заботятся о явном указании культуры, и все сводится, чтобы на всех серверах стояла в системе (т.е. внешней Environment) одинаковая культура (чем это плохо, и что происходит по ходу дела, думаю, не нужно объяснять).
XSD-схемы, платформенно-независимый формат XML? — не, не слышали.
И вот из-за одной даже такой мелочи (работа со строками) — вот как это применять на back-end?
В Java функции работы со строками работают так, что типы данных представляются в том формате, в котором значения типов записываются в коде самого Java-приложения, т.е., в инвариантном.
А для UI-представления нужно использовать класс Formatter.
Смена основного стека с .NET на Java