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-объектов.