Интервью Гаэля и Скота Хансельмана

Всем привет! Я хочу анонсировать и пригласить резидентов Москвы и Питера посетить бесплатные вечера и мастер-классы с автором одного из наиболее мощных АОП фреймворков для .Net — Гаэлем Фрётэром.
Встречи пройдут 11-13 марта в Москве и 16-17 марта в Питере. Еще раз повторюсь мероприятие бесплатное, но необходимо зарегистрироваться. Более подробно агенда представлена здесь

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

HM

СКОТТ ХАНСЕЛЬМАН: Всем привет, это Скотт Хансельман (Scott Hanselman) и в эфире новый эпизод Hanselminutes. Сегодня, с помощью магии скайпа, с другого конца мира, мы поговорим с Гаэлем Фрётэром (Gael Fraiteur) из SharpCrafters, создателем PostSharp. Привет!
ГАЭЛЬ ФРЁТЭР: Привет!
СКОТТ ХАНСЕЛЬМАН: Я очень рад, что сегодня могу поговорить с тобой. Я твой поклонник и нам предстоит многое обсудить. Сегодняшняя беседа входит в цикл бесед о стартапах и ты как нельзя лучше подходишь для этого. Ты человек из мира открытого ПО, и создал программу которой я пользовался для своих открытых проектов, но теперь ты построил на этом целую компанию. И я хочу понять почему ты сделал это? Затем мы немного обсудим сам продукт и его будущее. Итак, ты можешь начать с рассказа что за программу ты создал.
ГАЭЛЬ ФРЁТЭР: Мы создали PostSharp – это дополнение к компилятору, которое запускается после сборки проекта или, другими словами Аспектно-Ориентированный фреймворк. Его задача заключается в том, чтобы вы, как программист, создавали меньше тупого повторяющегося кода. Для примера можем рассмотреть такую штуку как реализацию уведомления об изменении свойства. Каждый раз для её использования вам надо написать три строчки кода. Эти три строчки кода – мелочь, но мелочь, которая должна быть реализована для каждого свойства в каждом классе, и они превращаются в тысячи строк кода. Можно обнаружить, что вы пишите реализацию по определенному шаблону и это приводит к лучшей реализации INPC. Наш инструмент позволяет реализовать этот шаблон так, что код будет генерироваться автоматически и не загрязнять исходный код. Это суть подхода PostSharp и аспектно-ориентированного программирования (АОП).
СКОТТ ХАНСЕЛЬМАН: Хм, аспектно-ориентированное программирование. Я слышал про него в рамках решений для сквозного функционала. Можно сказать, что люди думают вертикально при объектно ориентированном подходе: это наследуется от этого, вон то от другого. Но АОП, как например логирование, не вписывается в такую вертикальную иерархию. Оно прошивает эти иерархии через всё приложение. Я в верном ключе описал АОП подход?


ГАЭЛЬ ФРЁТЭР: Да, в точку. Разделение ответственностей – это ключевой принцип в разработке ПО. Когда мы думаем о реализации функционала, мы ожидаем увидеть единственный артефакт или реализацию. Например, если взять управление контактами, то это может быть единое пространство имен. Когда будет происходить поиск функционала для него, ты мы начнем с пространства имен, затем классов, методов и так далее. Мы ожидаем адекватного разделения ответственностей. Но потом мы начинаем подумывать о логировании или добавлении транзакционности, или обработки исключений, уведомлений об изменениях, безопасности. Все это пронизывает бизнес-логику приложения и это можно еще назвать ортогональной функциональностью. Упомянутые фичи используются почти везде, и они не могут быть адресованы с помощью вертикали классов, методов, процедур – именно поэтому в Пало Альто задумались над этой проблемой и пришли к принципу Аспектно-Ориентированного Программирования. Для Java есть очень мощные реализации АОП и PostSharp, в свою очередь, является мощной или даже самой мощной реализацией принципов АОП для .NET.
СКОТТ ХАНСЕЛЬМАН: Когда вы создали продукт? В какой момент разработки вы поняли, что это то что надо и вы обязательно доведете дело до конца? И как продукт стал открытым?
ГАЭЛЬ ФРЁТЭР: Я сразу сделал его открытым. Разработка началась, когда я работал в одном телекоме и нужно было создать систему наблюдения за процессами. Я почувствовал, что надо сделать код более интересным, решить задачу на более низком уровне – вот так и начал искать подход к решению проблемы. Это был 2004 год и разработка более-менее рабочей версии отняла у меня примерно 9-12 месяцев. Разработка велась каждый день вечером по часу-два. Через год я заметил, что люди стали интересоваться проектом, мне стали писать. Некоторые компании хотели спонсировать проект в обмен на скорейшую разработку интересующих их фич. Постепенно это становилось все более важным для меня. После примерно 3х лет, в 2007, я решил покинуть свою основную работу в телекоме и начать жить на заработки от фриланса, чтобы посвятить больше времени на разработку моего детища. Первоначальной идеей было посвятить 40% времени моему опенсорс проекту, который еще не приносил дохода, а остальное отдать на заказную разработку. Такой баланс продержался года два, но с ростом успеха 40% уже не хватало. Я стал уделять 50% времени, потом 60%. В этот момент я понял, что жить на оставшиеся 40% заказной разработки нельзя [у Гаэля жена и трое детей – прим.переводчика]. Пользователи наседали на меня с запросами поддержки, новых возможностей, просили подвести коммерческую базу – все вело к тому, чтобы организовать компанию вокруг существующего продукта. Я решил посоветоваться с бизнесом, который знаком с организацией стартапов и, с его поддержкой советами, стал разрабатывать новую версию продукта. Вообще опенсорс версия все еще доступна и бесплатна. Просто она не поддерживается. В итоге мы сделали новую версию с новым функционалом за 9 месяцев разработки и тестирования и стали ее продавать.
СКОТТ ХАНСЕЛЬМАН: Понятно. Ты упомянул несколько интересных моментов. Вообще ты рассказал много всего интересного, но давай вернемся немного назад. Ты начал опенсорсный проект. Он стал достаточно популярным, и ты решил покинуть работу на полный день, заняться консультациями и надеяться, что этого будет достаточно для работы над основным проектом.
ГАЭЛЬ ФРЁТЭР: Да
СКОТТ ХАНСЕЛЬМАН: Были ли твои консультации только по вопросам аспектно-ориентированного программирования или же это были общие консультации?
ГАЭЛЬ ФРЁТЭР: Все было связанно с PostSharp. В начале это был основной пункт контракта, но далее я стал работать над функционалом, не связанным с ядром продукта. Опенсорсный проект позволил мне стать заметным членом .NET сообщества и получать более выгодные заказы, что привело к тому, что я тратил только 60% на основной проект, а остальное на поддержку. Я думаю, что примерно такая же история у большинства контрибьютеров в опенсорс мире. Когда ты начинаешь вкладываться в значимый проект или начинаешь такой проект самостоятельно, появляются огромные перспективы, а затем и возможности, которые никогда бы не проявились следуй ты по указке своего менеджера или которые предоставляет твой родной небольшой город.
СКОТТ ХАНСЕЛЬМАН: Выглядит как очень простой и прямой путь делать бизнес. У тебя есть популярный проект, он с открытым кодом. У тебя есть активная база пользователей, которую ты консультируешь часть своего времени за деньги. Но потом, ты говоришь, что это стало отнимать 40%, 50%, 60% времени. Почему поддержка стала захлестывать тебя? Почему был такой рост?
ГАЭЛЬ ФРЁТЭР: Львиная часть всей работы связана с поддержкой фреймворков на которых работает ПО и разработкой новых возможностей. Когда вы только начинаете проект, у вас нет пользователей, а значит у вас нет необходимости согласовывать изменения – думаю, это справедливо для каждого проекта. Очень просто написать первые строки проекта. Но в дальнейшем, когда у вас есть пользователи, стоимость любого изменения вырастает вчетверо. Маржинальная стоимость изменения является функцией от всего существующего кода приложения, и это частая ситуация в мире разработки. Когда проекту уже 3 года и тысячи пользователей — это начинает оказывать серьезное влияние на поддержку новых в то время фреймворков: Silverlight, Azure. На тот момент было важно создать поддержку первой версии Azure. Компании, разработчики в больших компаниях стали использовать PostSharp и им нужны были какие-то гарантии что продукт будет развиваться и поддерживаться в будущем. Коммерческая организация в этом ключе выглядела лучшей гарантией для них. Независимые разработчики и компании в один голос твердили что они ждут коммерческой версии продукта.
СКОТТ ХАНСЕЛЬМАН: Отлично. Это уже становится интереснее, потому что я думаю, многие наши слушатели так же вовлечены в опенсорсные проекты или они об этом задумываются. Все согласятся, что работать над проектами с открытым кодом или начать такую работу легче, чем найти работу. И вот, если человек хочет получить опыт или, как ты сказал стать более заметным, он работает над опенсорс проектом. Но, когда проект достигает определенного размера или популярности, большие компании, энтерпрайз, начинают требовать большего. Они ожидают большего. Они ожидают целую организацию за проектом, как например фонд Apache или Outercurve Foundation, или Eclipse. Но когда начинается процесс миграции из опенсорс в мир коммерческой разработки, не рискуете ли вы потерять множество последователей? Вы что-то приобретаете, но и потерять можно костяк движения.
ГАЭЛЬ ФРЁТЭР: Да, когда вы делаете такой переход, вы меняете свою аудиторию. Конечно мы потеряли множество пользователей и много кармы за первые 6 месяцев, но потом мы разработали новую стратегию для привлечения новых пользователей, возвращения старых. Так что это вообще рискованный шаг был и гарантии успеха не было. Еще до перехода в коммерческий стан, да и во время его, я пробовал одну штуку, которая лично у меня не получалась, но истории успеха есть. Я пытался продать поддержку продукта. В общем в течении шести месяцев была коммерческая версия продукта, платная поддержка, лицензирование, но я продал только 3 или 5 лицензий и этого явно не хватало на жизнь. Кажется, это было в 2008 году. В сообществе есть мнение, что делая опенсорс проекты ты можешь жить без поддержки продукта, но для меня это оказалось не так. Если призадуматься над этим, то без поддержки это ситуация lose-win. Вы выигрываете за счет пользователей. Когда им требуется поддержка, это возможно означает что они в растерянности, у них проблемы и требуется помощь. Я думаю, что разработчики не очень любят обращаться в поддержку. Мы любим разбираться с проблемами сами. В моей ситуации, повторюсь, это не сработало, но я решил представить опенсорс версию и сказать людям: «Хэй, мы многое вложили в новую версию. Если вы хотите получить новые возможности, это будет за плату. Если не хотите, то у вас есть две возможности. У вас есть старая версия, которая все еще доступна. Или вы можете использовать версию под свободной лицензией.» Так мы пришил к тому что у нас появились версии Premium и Professional.
СКОТТ ХАНСЕЛЬМАН: Получается, что старая версия заморожена и закончена.
ГАЭЛЬ ФРЁТЭР: Да.
СКОТТ ХАНСЕЛЬМАН: Вы сделали новую ветку, двинулись в другом направлении или просто закончили свободный проект?
ГАЭЛЬ ФРЁТЭР: Нет, мы просто закончили проект. Некоторые сделали форк проекта, но никто не принял ответственность за код. Можно сказать, что та версия мертва. Но я думаю, что примерно 50% людей все еще используют старые версии PostSharp.
СКОТТ ХАНСЕЛЬМАН: Вообще та версия может случайно умереть окончательно, когда что-то поменяется в самом .NET фреймворке. Никто не поддерживает ту версию и изменения просто никак не отразятся в проекте, никто ничего не будет чинить, так?
ГАЭЛЬ ФРЁТЭР: Да. Например, та версия работает только для фреймворков до версии 3.5 включительно.
СКОТТ ХАНСЕЛЬМАН: Ох…
ГАЭЛЬ ФРЁТЭР: До сих пор огромное число разработчиков пилит проекты на стеке технологий версии 3.5.
СКОТТ ХАНСЕЛЬМАН: Какой совет вы можете дать нашим слушателям, которые занимаются открытыми проектами, которые уже сделали что-то значительное и обрели известность, которые начинают думать: «Хорошо, я уже сделал все это даром и получил свою дозу славы, но денег что-то не видать»? Должен ли каждый опенсорс проект достигший определенного уровня зрелости переходить на коммерческую основу?
ГАЭЛЬ ФРЁТЭР: Нет, я так не думаю потому, что я видел разные модели отличные от нашей, которые срабатывали. Сложно оценить работающие подходы в коммерциализации продукта, не зная внутренних механизмов и их показателей, да и не скажет этого никто. У вас может быть очень популярный проект и благодаря этой популярности будет много вопросов по продукту, и вы можете предлагать тренинги. На мой взгляд, это может быть даже более прибыльная модель получения денег, нежели перевод продукта на платную основу, потому что так вы теряете часть аудитории. Для части пользователей вы превращаетесь из героя в засранца из-за коммерциализации. Будет так же небольшая группа людей, которая будет слать вам письма с объяснениями какой же вы дурак. Но это меньшинство. Примерно 5% пользователей будут вам говорить обратное, что вы все делаете правильно. Так должны ли вы коммерциализировать свой опенсорс проект? Конечно это не очевидный выбор. Проанализируйте сначала другие стратегии и особенно подумайте над тем сможете ли вы привлечь помощников для разработки продукта. В случае с PostSharp желающих было так мало и проект был таким сложным, что я не мог найти помощников, когда перевел проект в опенсорс. В то время я был автором 99,7% всего кода.
СКОТТ ХАНСЕЛЬМАН: Очень похоже на правду, потому что даже такие простые и популярные проекты, как мой недалекий NerdDinner, не привлекает большого числа помощников. В первый год таковых было достаточно, но в последнее время над ним работаем только я и Jon Galloway, а также еще два хороших человека из сообщества: John Petersen and Peter Mourfield. Вы можете подумать, что мне шлют изменения 30, 40, 50 человек, но этого не происходит.
ГАЭЛЬ ФРЁТЭР: Ага.
СКОТТ ХАНСЕЛЬМАН: Потом, если добавляешь сложности, как например использование АОП, ты выбираешь все из меньшего и меньшего числа помощников, пока ты не обнаруживаешь себя один на один с проектом и тысячами и тысячами пользователей.
ГАЭЛЬ ФРЁТЭР: Именно. Существует момент, когда надо решить для себя, что для продолжения жизни проекта, для его роста и поддержки новых фич .NET хотя бы на минимуме – тебе придется платить людям за помощь иначе они сами не придут. Или вы можете найти помощника, который будет просить четкие задания. В результате такого микроменеджмента вы больше потеряете времени нежели выиграете. Такая ситуация была в 2006, 2007 когда SourceForge был центром открытой разработки.
СКОТТ ХАНСЕЛЬМАН: Когда вы пришли к коммерческой модели, закрыли ли вы репозиторий и как вы это сделали?
ГАЭЛЬ ФРЁТЭР: В целом вы должны быть единственным разработчиком на проекте, иначе у вас просто не будет прав это сделать. Вам нужно согласие от всех помощников и хорошо, если их небольшое число. Затем надо сменить лицензию по которой опубликован код. Так что я просто сделал новую версию с новой лицензией. Я предполагал, что часть проекта может остаться открытой для разработки плагинов, но я не нашел такой архитектуры, при которой можно очень строго разделить платные фичи от бесплатного куска кода и чтобы это можно было покрыть нормально лицензиями. Кстати, это еще одна штука которая может сработать в других проектах. Например, вы можете сделать свободную ERP, и создавать платные дополнения к ней. В случае с PostSharp так не получилось.
СКОТТ ХАНСЕЛЬМАН: Хорошо, давай теперь посвятим немного времени непосредственно PostSharp и тому, что он позволяет сделать. Поговорим немного о АОП. Если я понял все правильно, то если кто-то хочет поменять общее поведение всего приложения, как я уже упоминал про безопасность, логирование, обработка ошибок, то АОП выглядит почти как плагины, но это не плагины. Опять же если использовать аналогию с вертикалью классов, то мы не подключается в эту вертикаль, а прошиваем ее насквозь. Упомянутые концепции покрывают приложение ровными слоями. Но правда ли, что я могу сделать это не меня код приложения, и даже вообще не видя его?
ГАЭЛЬ ФРЁТЭР: PostSharp версии 2.0 [которая уже недоступна, и текущая версия 4.1 – прим.переводчика] принципиально построен на использовании атрибутов, так что вам надо будет добавить хотя бы одну строчку кода, но это будет файл assemblyInfo. Но да, это будет единственное изменение в коде. Это вообще оказалось хаком и не так мы задумывали использование на уровне сборки. Версия 2.0 была задумана только для модификации кода, которым вы владеете, а не произвольной сборки. Это должно было измениться в версии 3.0, которая позволит изменять что угодно. PostSharp широко используется атрибуты, но это не значит, что вы должны ими инструментировать каждый кусочек кода, который должен подвергнуться изменениям. Как было уже сказано, необходимо правильно составить фильтр использования атрибута на уровне сборки. Можно применить аспект только к публичным методам, только в определенном пространстве имен, например. Можно использовать возможности по рефлексии в момент сборки. Это очень круто, так как PostSharp запускается в момент сборки приложения сразу после того как отработает C# компилятор. Т.е. вы можете писать код для PostSharp используя рефлексию и таким образом добавить аспекты к чему угодно если оно написано на C#. Например, используя LINQ и рефлексию можно вернуть набор аспектов использованный в проекте.
СКОТТ ХАНСЕЛЬМАН: Помоги мне понять, как это все встраивается в процесс сборки. Потому что большинство людей пишут код, отдают его компилятору компании софтом которой пользуются, например Microsoft. Итак, они отдали код компилятору, он сделал IL и собственно всё. В какой момент именно вы вклиниваетесь?
ГАЭЛЬ ФРЁТЭР: PostSharp начинает работать сразу после компилятора. Он стирает MSIL, переписывает его, возвращает назад. На концептуальном уровне это можно рассматривать как расширение компилятора, но технически он запускается на этапе компиляции. Т.е. после (post) C#, PostSharp.
СКОТТ ХАНСЕЛЬМАН: Допустим. Т.е. это происходит сразу после компиляции и вы буквально берете бинарник и… нет, дайте перефразировать… то, что мы думаем есть бинарник, но на самом деле просто контейнер для IL кода. Вы открываете его и меняете итоговый код. Вы меняете то, что сделал C#.
ГАЭЛЬ ФРЁТЭР: Да.
СКОТТ ХАНСЕЛЬМАН: В процессе внедрения в IL, вы переплетаете IL словно это ваш код, как же я тогда смогу потом дебажиться?
ГАЭЛЬ ФРЁТЭР: Это достаточно просто, потому что когда PostSharp переправляет содержимое PDB файла, когда он вставляет дополнительный код, он так же вставляет точки перехвата, которые обновляют карту соответствий между бинарником и исходным кодом. Поэтому, когда вы дебажите программу, это происходит как обычно, без изменений, но теперь просто добавились аспекты. Если вы собираетесь войти внутрь метода и к нему применен аспект, то вы сначала войдете в тело аспекта и затем аспект вызовет оригинальный метод. Например, у вас есть кэширующий аспект примененный к методу. Точка остановки стоит на вызове метода. В момент остановки, вы нажимаете «Step to» и оказываетесь внутри аспекта, проходите весь его код и возвращаетесь в нужный метод, а дальше все как обычно.
СКОТТ ХАНСЕЛЬМАН: Т.е. это действительно бесшовный процесс?
ГАЭЛЬ ФРЁТЭР: Да
СКОТТ ХАНСЕЛЬМАН: Я предполагаю, что если бы вы изменили процесс отладки, так знакомый многим, то многие люди не так благосклонно приняли бы PostSharp. Но ты говоришь, что я могу просто нажать на F11, попасть в аспект и дальше все как обычно.
ГАЭЛЬ ФРЁТЭР: Да. Можно ставить точки остановки как обычно, в бизнес-коде, в аспектах. Если вы не хотите заходить в тело аспекта и каждый раз проходить его, просто потому что вы знаете что он есть и все с ним хорошо, вы можете использовать атрибуты из области имен System.Diagnostics. Например, DebuggerStepThrough.
СКОТТ ХАНСЕЛЬМАН: Что меня может побудить использовать АОП, а не построить свою собственную систему плагинов как, скажем, MEF? Почему я должен задумываться об АОП для внедрения чего-либо в мой собственный код?

ГАЭЛЬ ФРЁТЭР: Когда вы используете Dependency Injection у вас нет возможности внедрить новое поведение между клиентом и сервисом. И вся эта штука работает так, что когда клиент запрашивает интерфейс у контейнера, тот возвращает реализацию. Если же для реализации применяется аспект, например, логирование, то контейнер вернет вам по сути прокси-объект. Но это значит, что вы ограничены в применении нового поведения в силу самой природы работы между клиентом и сервисом. Это значит, что вы не можете таким образом проинструментализировать внутренние методы, статические методы, WPF компоненты. Т.е. набор точек внедрения аспектов для DI очень мал.
СКОТТ ХАНСЕЛЬМАН: Есть ли что-то, о чем я должен беспокоиться как разработчик? Или же аспекты просто плавно уходят на задний план, и я забываю, что они есть? В смысле я хочу сказать, что может ли происходить что-то такое во время выполнения аспектов что я не смогу отдебажить?
ГАЭЛЬ ФРЁТЭР: Из бесед с нашими старыми клиентами, которые пользуются PostSharp на протяжении трех или четырех лет, мы узнали, что основную пользу они видят не в том, на сколько строчек кода они смогли сократить код. Основная польза в том, сколько строчек кода надо прочитать при изучении проекта. В качестве примера можно привести истории, когда в команде появляется новый член, который ничего не знает об АОП, не понимает, что такое аспекты и только примерно через 6-8 месяцев он приходит к другим разработчикам с вопросом: «Ребята, а как все же реализована у нас поддержка транзакций?» Потому что это не прописано явно в коде, это просто магия. Итак, в течении этих 6-9 месяцев новый сотрудник пишет хороший код, который по идее требовал бы изучения многих вещей: кэширование, торговля на бирже, правила оформления транзакций. Но этого не потребовалось на первом этапе. Системный архитектор может просто понаписать аспектов и применять их к продуктовому коду, говоря этим «я хочу трассировку здесь» или «транзакционную логику там». Так что это может быть только плюсом, что вы не знаете, что аспекты есть.
СКОТТ ХАНСЕЛЬМАН: Интересный взгляд, потому что это получается еще один вид абстракции. Я хотел сказать, что это новый уровень абстракции, но думаю, что это именно новый вид. Вообще я думаю, что абстрагирование — это то, чем компьютеры и должны заниматься. Они предназначены для того, чтобы делать неинтересные вещи, и логирование это одна из самых невеселых вещей, да и обеспечение транзакционности тоже, так почему бы не спрятать их. Как ты думаешь, почему аспектно-ориентированное программирование до сих пор не поглотило умы разработчиков, почему не все его используют?
ГАЭЛЬ ФРЁТЭР: Я думаю, что одна из причин этого в том, что АОП был разработан как академическое исследование в лаборатории Xerox в Пало Альто, и первая реализация была очень академической с труднопонимаемыми концептами, так что кривая изучения была очень крутой с самого начала. Когда я начал разработку PostSharp в 2004-2005, я смотрел на это исследование и понимал, что это не тот путь которым я хочу следовать. В .NET можно создавать свои атрибуты, и они более естественно подходят для реализации и представления аспектов. В этом плане мы не вводим новых концепций. Я начал разработку с очень простого фреймворка, который звался LAOS — Lightweight Aspect-Oriented System и он стал весьма популярным. Эта версия не была такой сложной, как существовавшие на тот момент. Например, как AspectDNG или AspectSharp или все клоны AspectJ. Тогда я еще подумал, что возможно проблема в понимании концепции и поэтому многие люди были убиты сложностью. На данный момент, основным нашим заказчиком является не индустрия разработки средств программирования, но область финансов и здравоохранения. Наиболее полезным АОП оказывается в сфере разработки реальных бизнес-приложений.
СКОТТ ХАНСЕЛЬМАН: Точно. В большом и серьезном энтерпрайзе, где работа должны быть просто сделана, архитектор или инициативная группа может создать необходимые реализации в аспектах для снижения затрат в конкретных проектах. В дальнейшем бизнес-программисты могут сфокусироваться на решении доменных задач, а все остальное можно отдать на откуп автоматике.
ГАЭЛЬ ФРЁТЭР: Именно!
СКОТТ ХАНСЕЛЬМАН: Что ж, спасибо большое что поговорили со мной сегодня. Призываю всех слушателей посетить сайт https://www.postsharp.net, где вы можете загрузить подходящую версию PostSharp. Попробуйте! Установите версию Ultimate и используйте пробный период, чтобы посмотреть на все возможности программы. Вы потом всегда сможете перейти на бесплатную версию без переустановки. На сайте программы есть отзывы от многих известных людей по поводу удобства, например, Айенде (Ayende) из NHibernate [а так же и от самого Скота – прим.переводчика]. Еще раз спасибо, Гаэлю, за то, что он согласился поучаствовать в шоу и поговорить о своем стартапе.
ГАЭЛЬ ФРЁТЭР: Спасибо, Скотт.
СКОТТ ХАНСЕЛЬМАН: В эфире был очередной выпуск Hanselminutes, увидимся на следующей неделе.

Оставить комментарий