Архив за месяц: Апрель 2016

Импорт конфигурационных настроек сервисами и клиентами WCF

В некоторых случаях службы и клиенты удобно реализовывать в виде отдельных DLL, которые затем могут быть использованы различными приложениями. Например: MyService.dll и MyClient.dll. Предполагается, что они будут находиться в подкаталогах ./Extensions/MyExtensionName/ хостовых приложений, дабы при необходимости оный контент всегда можно было бы просто удалить даже вручную, не зацепив при этом случайно ресурсы основного приложения.

Однако, будучи подгруженными в хостовое приложение они, как и любые другие DLL, по умолчанию будут искать свои настройки в составе конфигурационного файла этого приложения. Всё же мне бы не хотелось в чужой config-файл вносить правки, необходимые для работы моих сервисов или клиентов, ну или хотелось бы, по крайней мере, минимизировать объём таких корректировок настолько, насколько это возможно... На мой взгляд, предпочтительным способом была бы возможность сохранения нужных мне настроек в отдельных конфигурационных файлах, находящихся рядом с соответствующей DLL моего сервиса или клиента, т.е. в файлах MyService.dll.config и MyClient.dll.config.

Экспорт конфигурационных настроек на стороне сервиса
Начиная с .NET 4.5 в классе реализации сервиса можно определить метод Configure со следующей сигнатурой:

public static void Configure(ServiceConfiguration config)

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

public static void Configure(ServiceConfiguration config) {
    ExeConfigurationFileMap configMap = new ExeConfigurationFileMap();
    configMap.ExeConfigFilename = typeof(MyService).Assembly.Location + ".config";
    Configuration dll_config = ConfigurationManager.OpenMappedExeConfiguration(configMap,
        ConfigurationUserLevel.None);
    config.LoadFromConfiguration(dll_config);
}

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

Например, если расширение хранится в каталоге %AppData%/CompanyName/ApplicationName/Extensions/MyExtensionName/ с тем, чтобы предоставлять пользователю возможность править конфигурационные настройки или вовсе удалять расширение, то нужным вариантом будет второй.

А если пользователь не имеет административных прав и расширение хранится в каталоге %ProgramFiles%/CompanyName/ApplicationName/Extensions/MyExtensionName/, то в данном случае вариант использования - это дело вкуса администратора.

Экспорт конфигурационных настроек на стороне клиента
На стороне клиента использовать метод Configure в коде наших прокси не получится, но начиная с WCF 4.0 нам в помощь появился класс ConfigurationChannelFactory. Его можно создать в конструкторе создаваемого нами прокси  и использовать в процессе работы например так:

[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class Drawing : IDisposable, IDrawing {

    IDrawing Channel;
    ConfigurationChannelFactory<IDrawing> channelFactory;

    public void Open() {
        if (channelFactory.State != CommunicationState.Opened &&
            channelFactory.State != CommunicationState.Opening)
            channelFactory.Open();
    }

    public void Close() {
        if (channelFactory.State == CommunicationState.Opened)
            channelFactory.Close();
    }

    public CommunicationState State
    {
        get { return channelFactory.State; }
    }

    public Drawing(string endpointName) {
        ExeConfigurationFileMap configMap = new ExeConfigurationFileMap();
        configMap.ExeConfigFilename = typeof(Drawing).Assembly.Location + ".config";
        Configuration dll_config = ConfigurationManager.OpenMappedExeConfiguration(configMap,
            ConfigurationUserLevel.None);
        channelFactory =
            new ConfigurationChannelFactory<IDrawing>(endpointName, dll_config, null);
        Channel = channelFactory.CreateChannel();
    }

    public void Dispose() {
        if (channelFactory != null&& channelFactory.State == CommunicationState.Opened)
            channelFactory.Close();
    }

    // here is other members...   
}
Обратите внимание на то, что в процессе реализации нужного нам прокси мы обошлись без наследования от класса ClientBase.

Ссылки:

Об использовании событий pre-build и post-build в Visual Studio

В некоторых проектах, создаваемых при помощи Visual Studo, возникает необходимость выполнения различного рода дополнительных операций в pre-build [и | или] post-build.

Если исходный код проекта находится в сети, а не на локальном диске, то открывать его следует в Visual Studio через предварительно подключенный сетевой диск. Т.е. например, если исходный код проекта находится в каталоге "\\hyprostr\dfs\groups\developers\src\DwgSaveAs\", то следует предварительно создать сетевой диск при помощи команды NET ADD:

net add Y: "\\hyprostr\dfs\groups\developers"

После этого, открывать в IDE проект, находящийся в сети, всегда следует путём указания каталога "Y:\src\DwgSaveAs\", вместо его сетевого имени "\\hyprostr\dfs\groups\developers\src\DwgSaveAs". В этом случае значения переменных ProjectDir, TargetDir и т.п. будут так же содержать значения, начинающиеся с "Y:\", а не с "\\hyprostr\". Это позволит в pre-build и post-build использовать команды такие как COPY, т.е. такие, которые обычно не могут работать с UNC-путями.

Предположим, что в событии post-build нашего проекта размещена такая команда:

COPY /Y "$(ProjectDir)teigha_vc11_amd64dll\*" "$(TargetDir)*"

Если проект будет открыт в IDE с использованием сетевого пути ("\\hyprostr\..."), а не сетевого диска "Y:\...", то попытка выполнить операцию, обозначенную в post-build будет неудачной. Если же проект будет открыть с использованием сетевого диска, то обозначенная в команде операция будет выполнена успешно.

Циклы в pre-build и post-build

Обозначенная выше команда, размещённая в post-build, может оказаться нецелесообразной в использовании, если выполняется копирование большого количества файлов. В подобных случаях процесс сборки проекта может занимать времени больше, чем нам бы того хотелось. Да и вообще, каждый раз выполнять копирование файлов, не подвергавшихся изменению, не целесообразно...

Порой нам нужно копировать только такие файлы, которых ещё нет целевом каталоге. Например, это могут быть файлы библиотек сторонних разработчиков. Чтобы копировать только отсутствующие в целевом каталоге файлы, в нашем post-build предыдущий вариант команды можно заменить таким:

For %%F In ("$(ProjectDir)teigha_vc11_amd64dll\*.*") Do If Not Exist "$(TargetDir)%%~nxF" Copy "%%F" "$(TargetDir)%%~nxF"

Внимание!
Обратите внимание на то, что все символы % в данном случае должны быть продублированы. В этом нет необходимости в BAT-файлах, но при использовании подобных выражений в составе pre-build или post-build проектов Visual Studio такая потребность имеется.

Примечание
Несмотря на то, что решения открываемые через сетевой диск отображаются в группе Recent вкладки Start Page, тем не менее Visual Studio 2015 Update 2 не умеет их открывать через соответствующую ссылку, если пытаться сделать это сразу после запуска IDE. При попытке сделать это, появляется такое окошко:


Чтобы открыть решение через сетевой диск, сразу после запуска Visual Studio, придётся выбирать пункт Open Project на вкладке Start Page, или же сделать это через меню File -> Open Project/Solution. Кроме того, работает и способ открытия sln-файла решения (из сетевого диска) в Проводнике Windows.

Если затем закрыть решение, не завершая при этом работу IDE (т.е. при помощи пункта меню  File -> Close Solution), то соответствующая ссылка на решение в группе Recent будет работать. Причём работать будет и в том случае, если выбрав пункт меню File -> Open Project/Solution затем перейти в каталог решения и нажать кнопку Cancel - после этого, соответствующая ссылка в Recent сможет открывать решение. Правда всё это работает только до перезапуска IDE...


Книги, которые перевернут вашу жизнь

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

Первой книгой однозначно станет БИБЛИЯ. Это книга, к которой вы должны прийти. Это не та книга, которую нужно заставлять себя читать. Всему свое время.

«Атлант расправил плечи» также является достаточно интересной и полезной книгой. Это книга, которая меняет ваше впечатление, снимая розовые очки. Данная книга расскажет о том, что абсолютно каждый человек должен заниматься своим делом, а не приносить себя в жертву другим обстоятельствам. Самопожертвование тут рассматривается как самое ужасное, что может произойти у человека. Не нужно пытаться спасти мир. Намного полезнее будет, если каждый будет хорош выполнять то, что он умеет.

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

«Сказать жизни Да!» — отличная книга, которая расскажет вам про историю психолога, который сумел выжить в концлагере. При этом его рассказ о концлагере будет настолько жизнерадостным, что все ваши беды покажутся вам сущим пустяком. Это та книга, которая поможет в самую трудную минуту и которая навсегда изменит ваше представление о сложной ситуации.

«Поллианна. Юность Поллианны» — обязательно закиньте эту книгу в вашу электронную читалку. Как до сих пор не приобрети? Тогда вам нужно обратить внимание на сайт vivostore.ua, где и представлено огромное множество. Эта книга научит вас играть в достаточно интересную и полезную игру, которая называется «радость». Смысл этой игры заключается в том, что бы абсолютно в любой жизненной ситуации увидеть какой то позитив. По рассуждениями Полианны абсолютно любая ситуация имеет положительную сторону. Ваша задача — ее найти.

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

Planing Poker

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

К решению были предъявлены следующие требования:
1. Простота
2. До окончания оценки никто не видит оценок остальных участников.
3. Считать среднюю оценку.
Пункт два возник из-за того, что как только первый ставит оценку (мы до этого использовали для совместной оценки Skype), все остальные начинают под нее подстраиваться, особенно если этот первый программист с большим опытом.
Ну а пункт три это к вопросу о том, что в долгое время работающих в одном составе командах, оценки особо не нужны (подробнее писал ранее здесь).
Итак, что собой представляет приложение.
Для простоты оно состоит из вебсервиса (без базы данных и с отсутствующей персистентностью), который отвечает за взаимодействие клиентов и клиентского приложения, которое запускают у себя участвующие в оценке.
Вот так выглядит главное окно (картинки кликабельны):
При входе необходимо указать имя и с какой ролью входит участник. А дальше для ведущего есть возможность указывать номер оцениваемого требования и завершать оценку, для всех есть возможность перейти по ссылке (номер оцениваемого требования) в систему управления задачами и вторая доступная возможность поставить оценку. Ведущий и все участники оценки имеют возможность видеть кто уже оценил (минус - оценки еще нет, плюс - оценку участник уже поставил). Как только все оценили (оценку если что можно и менять в процессе обсуждения), ведущий нажимает кнопку показать результаты оценки:
Показывается кто как оценил и среднее. Если оценки очень сильно разняться, можно еще раз обсудить, но в  большинстве случаев можно сразу брать среднее и ставить его в требование.
Вот такое простенькое приложение нам немного облегчает жизнь каждые две недели.

Время идет, ничего не меняется


Это самое ужасное рассуждение: если я не могу всего — значит, я ничего не буду делать.
 -- Лев Николаевич Толстой

Вот здесь, несколько картинок и рассуждений по Chaos Report 2015. Кому интересно, можно пойти и посмотреть в оригинале. Пару картинок которые мне показались интересными, я утащил под кат.

Первая картинка самая говорящая и именно она послужила причиной такого заголовка у этой заметки. Действительно, за последние 5 лет особо заметных изменений нет (картинки кликабельны):
Как была полностью успешна треть проектов, так и остается. Ровно половина проектов завершается со срывом сроков, запланированного объема работ или бюджета. И почти пятая часть от всех проектов так и не доходит до пользователей.
Вдумайтесь, за эти пять лет прошли тысячи конференций, выпущены миллионы книг и все это про то как писать код, управлять требованиями, проектировать архитектуру и в целом управлять проектами. В этот же период на смену четвертому PMBook вышел пятый. А воз и ныне там. Может мы не тем занимаемся?
Еще интересная картинка:
Из всех успешных проектов за 5 лет 62% это маленькие проекты! Т.е. если запускаешь средний или больше проект, шансы уложиться в срок и деньги составляют менее 7%. Одна пятнадцатая. Шансы вообще его хоть как-то выпустить в этом случае составляют 25%. Четверть! Впечатляет.
Ну и последняя картинка. Какие факторы наиболее важны для попадания в треть счастливчиков:
Как видно из картинки успех проекта на 60% состоит из поддержки руководства, эмоциональной зрелости (насколько люди хорошо взаимодействую друг с другом), вовлеченности пользователей и оптимизации процессов (в том числе, разбиением крупных проектов на мелкие).
Самое забавное, это Agile находящийся на 7 позиции. А анекдот здесь в том, что именно Agile говорит что надо взаимодействовать с пользователями, выпускать продукт инкрементально (в виде небольших проектиков закрываемых за две недели и поставляемых пользователю), а уж оптимизация процессов в Agile это один из ключевых моментов. Но ладно пусть будет седьмое место.
Вот так и живем...

Книги в PDF формате, доступные для скачивания

На ресурсе http://www.allitebooks.com/ выкладываются книги в формате PDF, доступные для свободного скачивания. Библиотека пополняется ежедневно (ну или почти ежедневно). Пользуюсь давно.  По указанной ссылке книги не испорчены (как это зачастую бывает в наше время) переводом с английского на русский язык. Я редко встречал качественный перевод, в виду чего с некоторых пор предпочитаю читать на языке оригинала.

Если кто-то знает адреса подобных (качественных!) ресурсов - обозначение их в комментариях темы приветствуется.

Цитата дня


Проблема в том, что идиоты — самоуверены, а умные — полны сомнений.
 -- Бертран Рассел
P.s. Я понимаю, что объясненный анекдот, это не анекдот, но рекомендую посмотреть что писал  в своих философских трудах автор этой цитаты по поводу религии.

XslCompiledTransform и OutOfMemoryException

Столкнулся с проблемой, что при использовании xslt преобразований возникает Out Of Memory, если входной XML файл имеет достаточно большой объем, а приложение в ресурсах ограниченно, например по тому, что работает в 32-х разрядной системе. Под катом способы, как с этим можно бороться.

1. Отключение отладки

Если вызвать конструктор по умолчанию для XslCompiledTransform, то он автоматически включает режим записи отладочной информации. Во время отладки это может быть и полезно, но вот в работающем приложении это лишняя память. Поэтому надо пользоваться конструктором с булевым параметром и в явном виде ее отключать:

XslCompiledTransform xslt = new XslCompiledTransform(false);

2. Предварительная компиляция XSLT

Как это не странно звучит, но для того чтобы применить XSLT преобразование к XML файлу, файл содержащий это преобразование надо скомпилировать. Можно сэкономить память, если сделать это предварительно ручками.
Для этого, необходимо по пути вида:
C:Program Files (x86)Microsoft SDKsWindowsv8.1AbinNETFX 4.5.1 Tools
найти утилиту: xsltc.exe
и запустить ее указав какой файл с xslt преобразовать, в какую сборку и с каким именем класса записать получившийся код.
Получится что-то вида:
xsltc.exe /class:ClassName /out:OutputXSLT.dll input.xslt
Дальше все просто, подключаем сборку в проект, ну или загружаем ее во время выполнения через Reflection.
Все, теперь вместо пути к файлу, можем указать тип из нашей dll:

XslCompiledTransform xslt = new XslCompiledTransform(false);
xslt.Load(typeof(ClassName));

3. Если приходится преобразовывать много файлов одним XSLT

Во-первых, один раз создав XslCompiledTransform держим его в памяти и не пересоздаем.
Во-вторых, незабываем чистить память под поток записи результатов. Например, так:

using (XmlWriterxmlWriter = XmlWriter.Create(outputFileName))
{
    xslt.Transform(InputXmlFileName, xmlWriter);
}

4. Общее

Ну и последнее, можно попробовать собрать проект в Release конфигурации, может и на этом что-то полуситься выграть по памяти.

И снова о хостинге WCF-сервисов в 2016-м accoreconsole.exe…

Подумал тут... Вполне возможно, что Autodesk умышленно прикрыла возможность хостинга сервисов в 2016-м accoreconsole.exe, дабы если не полностью пресечь (т.к. это не возможно), то хотя бы максимально усложнить возможность использования инструмента в системе распределённых приложений взаимодействующих через сервисы...

Наличие возможности хостинга WCF-сервисов в accoreconsole.exe для ряда случаев может существенно сократить потребность в количестве приобретаемых лицензий AutoCAD на предприятиях, где выполнение некоторого (если даже не всего) объёма работ можно автоматизировать (т.е. сделать программно). Одним сервисом или набором сервисов (читать как "одной лицензией AutoCAD") в таком случае сможет пользоваться неограниченное количество сотрудников компании одновременно. Для компании клиента это, безусловно, экономия... Но вот для компании Autodesk - это потеря денег... Т.е. налицо явный конфликт интересов и вполне очевидно, кто в данной ситуации имеет на руках "все козыри".

Кроме того, не стоит забывать, что теперь в Autodesk хотят одних и тех же овец стричь каждый год (новая ценовая политика) в виду чего даже сама по себе потенциальная возможность  сокращения лицензий вряд ли будет воспринята ими положительно. Т.о., как я уже писал выше: не исключено, что в 2016-м AutoCAD "кислород" сервисам был перекрыт преднамеренно...

Резюме
Я не удивлюсь, если в более новых версиях AutoCAD приложение accoreconsole.exe будет вовсе тихо изъято, мол "за ненадобностью"...

Уильям Чемберс. История ландшафтного искусства

Уильям Чемберс

Предоставленный материал с сайта — http://tatufoto.ru/.

Уильям Чемберс, о теоретических работах которого упомянуто выше, был сыном йоркширского торговца, который жил в Стокгольме. В ранней молодости он поступил на службу в Шведско-Ост-Индскую компанию и имел случай побывать в Ост-Индии и Китае. Там в свободное время он зарисовывал постройки и сады, материал для будущих своих диссертаций, многого, кажется, не видел, потому что считает, что китайские сады малы, а в диссертации упоминает название только одного. По возвращении Чемберс бросил торговлю, занимался в Париже у Клериссо, где встретился с братьями Адамами и, может быть, Камероном, пробыл несколько лет в Италии. Первой его работой было устройство садов Кью около Лондона и постройка там целого ряда сооружений. Потом он заканчивал устройство садов Вильтона, Тэнфилд-холла, Марино около Дублина, где соорудил великолепный дворец, строил колоссальный Соммерсет-хауз в Лондоне и т. д.

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

Местность около ручья была красива благодаря отдельным красиво разросшимся деревьям и виду на храмики Эола и Беллоны. Теперь этого пейзажа не существует, так как деревья сильно разрослись, и сочетание пышных крон их с группами кустарников есть главное украшение садов. Маленькие храмики Чемберса красивы по форме, но поражают своей ненужностью и слишком малы, чтобы быть существенным дополнением пейзажа. Один из них, в виде ротонды с круглым куполом, доставлен на невысоком холме на берегу пруда; он красив в сочетании с окружающими рощами и красиво отражается в воде пруда.

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

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

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

Чемберс поместил в Кью и излюбленное, но мало удачное украшение пейзажных садов — искусственные развалины. И по форме плохо верится в подлинность этой полуразрушенной арки, и помещена она неудачно, не в укромном углу под зеленой листвой деревьев, а на хорошо содержимой аллее вблизи от каменной стены сада. Вообще, ввиду небольшого размера сада, Чемберсу пришлось все главные украшения отодвинуть к краям. В настоящее время сад Кью является наибольшим по размеру ботаническим садом Европы.