Delphi, Dependency Injection и архитектура...

100 views
Skip to first unread message

web.darked

unread,
May 28, 2013, 6:33:28 AM5/28/13
to dotne...@googlegroups.com
 Доброе время суток.
   Программирую на Delphi , но постоянно читаю ваш новости из мира .Net для "портирования" паттернов и практик программирования в своих  Delphi продуктах.  Прошу совета по реализации уровня сервисов в своём приложении.

   Следуя Dependency Injection, нужно в конструкторы "инжектировать" экземпляры классов, вместо создания их в конструкторе конечного класса. Но где - то же должны быть созданы инжектируемые объекты, где должна быть эта точка?

   Попробую пояснить на абстракции текущего проекта (прикрепил набросок со схемой). Не забываем что речь идёт о Delphi, где многое реализуется на готовых компонентах.

   Имеем:
 - TDataModule - невизуальный контейнер-хранилище, в данном случае открытых соединений с базами данных 1 и 2, для последующего использования их в других частях программы.
 - TMainForm  - главная форма приложения, где используются интересующие меня классы.
 - TBaseDBManager - родительский класс с реализацией базовых операций с базой, который в конструкторе требует экземпляр класса с открытым соединением с базой: constructor Create(ADbConnection: TFirebirdConnection)
 - TFileManager, TProjectManager - наследники TbaseDBMAnager, которые реализуют уже логику работы с файлами проекта и данными проекта как такового.


  Создаются эти классы в TMainForm, то есть там при создании я должен передать TFirebirdConnection - открытые соединения с базой. Тогда получается что форма должна знать о базе и где взять эти соединения, соответствующим include. Если я делаю include  в TBaseDBManager, то я там жёстко прописываю что FDBConncection = TDataModule.Connection (упрощённая запись).

   Ка в таком случае  лучше поступить?Встроенное изображение 1

Андрей Чистяков

unread,
May 29, 2013, 3:55:42 AM5/29/13
to dotne...@googlegroups.com
Добрый день,

У меня также большой (и относительно успешный) опыт портирования практик с C# на Delphi, так что думаю, что смогу Вам помочь. Но, наверное, будет не совсем корректно обсуждать Delphi в конференции по .NET, поэтому, думаю будет удобнее обсудить Ваши вопросы по почте / аське; можете мне написать на spa...@mail.ru.

Если вкратце ответить на Ваш вопрос относительно создания инжектируемых объектов:  сделать активную инжекцию зависимостей в полном смысле, как это делается в .NET с помощью библиотек IoC-контейнеров не получится. В любом случае программисту придется самому контролировать создание объектов, например, с помощью паттерна ServiceLocator:

MyObject := ServiceLocator.Resolve<IMyInterface>()

Это Вам придется писать либо в конструкторе, либо в коде, вызывающем конструктор, и передавать в него в качестве параметров.

Можете также погуглить информацию о библиотеке Delphi Spring, в ней есть IoC-контейнер (точнее, он так там называется, на самом деле это чистейший ServiceLocator).

Вообще, большинство паттернов и практик реализуемы в Delphi, но, к сожалению, код будет выглядеть гораздо менее красиво, чем аналогичный код в C#/Java - это связано с ограничениями языка (отсутствие GC и как следствие необходимость вызывать деструкторы объектов; крайне неудачная реализация интерфейсов, завязанная на COM; отсуствие удобного синтаксиса для лямбд, из-за чего они практически непригодны для использования).

Максим Еленов

unread,
May 30, 2013, 6:14:58 AM5/30/13
to dotne...@googlegroups.com
Если не использовать Ioc-контейнер, то все зависимости нужно передавать где - то в одном месте при старте программы. Например в методе main. Лучше это даже сделать в отдельной сборке.
Reply all
Reply to author
Forward
0 new messages