12 дек. 2010 г.

JDK,Scala & IDEA 10 & Ubuntu 10.10 How To ?

Не так давно я решил некоторые проблемы со своим ПК, и наконец-то выделил дисковое пространство для ubuntu 10.10. После установки системы я начинаю подготавливать рабочую среду. По своему роду деятельности мне приходится разрабатывать гибридные .NET/Java проекты. Первым делом на новой системе мне нужно установить JDK. К сожалению по умолчанию в ubuntu 10.10 идет OpenJDK. Это нам совершенно не подходит. Приступаем к установке Sun/Oracle JDK.

1.Смотрим что у нас установлено из OpenJDK:
sudo dpkg --get-selections | grep openjdk

2.Удаляем все пакеты с OpenJDK:
sudo apt-get remove openjdk-6-jre-headless

По идее можно сделать так:
sudo dpkg --get-selections | grep openjdk > sudo apt-get remove, но я не пробовал

3.Ставим Sun/Oracle JDK:
sudo add-apt-repository ppa:sun-java-community-team/sun-java6
sudo apt-get update
sudo apt-get install sun-java6-jdk

4.Проверяем версию Java:
$ java -version
java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
Java HotSpot(TM) Client VM (build 17.0-b16, mixed mode, sharing)

Теперь скачаем последнюю версию Scala. Смело идем на scala-lang.org и качаем.
Я ставлю Scala в каталог /opt/scala, и прописываю пути до него в PATH

Далее качаем последнюю версию IDEA Community Edition. На момент написания статьи была версия 10.0. Распаковываем архив куда вам угодно и запускаем IDEA.
Сразу идем File - Settings - Plugins и ставим свежий плагин Scala (не Scala Power Pack).
Перезапускаем IDEA и можно уже создавать Scala проекты.
Еще ремарка, в Run configurations выбираем шаблон Application, указываем главный класс и проект. Основной класс программы должен реализовывать def main(args: Array[String]), пример:

object App {
def main(args: Array[String]) {
println("Hello world!")
}
}

8 апр. 2010 г.

Dependency Injection на примере с Autofac

Доброе время суток!
В этом посте мы на примере разберем понятие dependency injection (внедрение зависимости).
Для начала хочу рассказать по своему опыту. У меня был проект, довольно сложный. В погоне за правильной архитектурой приложения я разбил проект на модули. Проект заработал и был запущен в production. Все бы было хорошо, пока дело не дошло до внесения изменений в функционал/код. Большие зависимости между классами вызывали трудности при тестировании и внесении изменений в код. На моей электронной полке к тому времени уже давно лежала книжка Dhanji R. Prasanna Dependency Injection.
Т.к. проект у меня был на .NET я начал искать IoC контейнеры в реализации для этой платформы.

Найдены были:
Почему Windsor на первом месте ? :) Потому что как-то давно, я уже делал на нем простые примеры. Но сейчас мой выбор пал на AutoFac. Аргументы ? Во-первых проект очень быстро развивается. Уже сейчас, еще до выхода .NET Framework 4.0, уже есть поддержка последнего фреймворка. Это не может не радовать! Во-вторых уже сейчас в AutoFac есть поддержка WCF, MEF, ASP.NET MVC. Поддержку MEF выделяю особенно. Ну и в-третьих мне понравилась архитектура библиотеки, все ясно и понятно.

И так, рассмотрим работу AutoFac на небольшом примере. Для начала создадим консольный проект. В этом же solution создадим class library и назовем её IfaceLib. В этой библиотеке опишем 2 интерфейса.

public interface ILibOne
{
string getMyName();
}
public interface ILibTwo
{
string getMyFullName();
}

Теперь создадим еще одну class library и назовем её LibOne. В ней мы реализуем интерфейс ILibOne в классе LibOneClass. Перед этим не забудем зареференсить сборку IfaceLib.

public class LibOneClass : ILibOne
{
public string getMyName()
{
return "Spectrum";
}
}

Создадим еще одну class library и назовем её LibTwo. В ней мы реализуем интерфейс ILibTwo в классе LibTwoClass.

public class LibTwoClass : ILibTwo
{
ILibOne one;

public LibTwoClass(ILibOne one)
{
this.one = one;
}

public string getMyFullName()
{
return "ZX " + one.getMyName();
}
}

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

class Program
{
static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<LibOneClass>().As<ILibOne>();
builder.RegisterType<LibTwoClass>().As<ILibTwo>();
builder.Register(c => new LibTwoClass(c.Resolve<ILibOne>()));
var container = builder.Build();

var two = container.Resolve<ILibTwo>();
Console.WriteLine(two.getMyFullName());
Console.ReadLine();
}
}

Разберем что у нас происходит в коде программы.
Для начала мы создаем контейнер:

var builder = new ContainerBuilder();

Регистрируем типы:

builder.RegisterType<LibOneClass>().As<ILibOne>();
builder.RegisterType<LibTwoClass>().As<ILibTwo>();

Далее мы определяем поведение контейнера, при создании LibTwoClass. Ведь в этом классе есть зависимость от LibOneClass. В следующей строке мы указываем контейнеру, как ее разрешить:

builder.Register(c => new LibTwoClass(c.Resolve<ILibOne>()));

Таким образом, при создании LibTwoClass контейнер автоматически разрешит зависимость, и подставит заместо ILibOne экземпляр LibOneClass.
В результате выполнения программы на экране мы получим:

ZX Spectrum

Что нам дает использование IoC контейнера ? Мы можем писать самодостаточные классы без разрешения зависимостей между ними. Мы можем проводить независимое юнит-тестирование каждого класса. Мы можем безболезненно вносить изменения в класс.

На этом у меня пока все. В следующем топике постараюсь рассказать про использование mock-объектов.

9 янв. 2010 г.

Corel Draw X3 на Ubuntu 9.10


Всем хороша Ubuntu 9.10. Но на одном из проектов возникла острая необходимость работать с Corel Draw. В такой ситуации есть 3 выхода:
1. Использовать Corel Draw на родной Windows платформе.
2. Установить Windows в Sun Virtual Box и туда же Corel Draw
3. Попытаться запустить Corel Draw через WINE.

Первый вариант не подходил изначально, т.к. это постоянные перезагрузки ПК для работы то в Windows, то в Linux. Второй вариант утомителен. Установка операционной системы в виртуальную машину только для того, что бы запустить Corel Draw. Третий вариант... Остался только он. Сразу же скажу, что с WINE я практически не работал. На рабочей Linux машине стоит WINE версии 1.0.1 из репозитария Ubuntu. Самый верный способ избежать возни с версиями dll это скачать portable версию продукта, что я и сделал. И так на машине имеем распакованную portable версию Corel Draw X3. Переходим в корневой каталог программы и пишем магическую команду:
wine ./CorelDRW.exe

Попытка запуска не удалась. Не хватает библиотеки mfc42.dll. Библиотека была успешно скопирована с рабочей Windows в папку с Corel Draw. Повторно набираем магическую команду, и вуаля! Corel Draw запущена.

Некоторые замечания по работе. Прорисовка окон будет заметно быстрее если в корневую папку программы вы дополнительно скопируете библиотеки:
mfc42loc.dll, mfc42rus.dll, mfc42u.dll

Corel Draw успешно падает при слишком быстром прокручивании списка шрифтов. Со шрифтами стоит быть осторожнее. Буфер обмена так же не работает. Поэтому объекты копировать не получится.

Это пока основное что я заметил.