Сообщение Re: Точка создания и инициализации конкретики приложения от 08.05.2024 17:35
Изменено 09.05.2024 9:42 RushDevion
Re: Точка создания и инициализации конкретики приложения
Z>Получается, в начальной точке приложения должен быть какой-то супер-класс, который знает про особенности инициализации всех инфраструктурных слоев приложения.
Z>Верно?
Да. Это место так и называется "точка сборки", "корень композиции", composition root и т.п.
Z>Но тогда получается, что это "плохой" God-объект.
It depends.
Z>Как же быть?
Z>Как делать инициализацию? В какой точке? И в каком месте указанной картинки эта точка должна располагаться?
Инициализация делается в той точке где приложение стартует. Что, если подумать, логично, где еще ее делать-то?
А вот как именно ее делать — тут возможны варианты.
Далее я даю примеры на .NET/C#, потому что работаю в основном с этим окружением, но, думаю, в Java принципиальных отличий не будет.
1. Прямолинейный — собираем граф зависимоcтей руками (aka pure man DI)
2. Используем контейнер внедрения зависимоcтей (aka DI-контейнер, IOC-контейнер)
Z>Верно?
Да. Это место так и называется "точка сборки", "корень композиции", composition root и т.п.
Z>Но тогда получается, что это "плохой" God-объект.
It depends.
Z>Как же быть?
Z>Как делать инициализацию? В какой точке? И в каком месте указанной картинки эта точка должна располагаться?
Инициализация делается в той точке где приложение стартует. Что, если подумать, логично, где еще ее делать-то?
А вот как именно ее делать — тут возможны варианты.
Далее я даю примеры на .NET/C#, потому что работаю в основном с этим окружением, но, думаю, в Java принципиальных отличий не будет.
1. Прямолинейный — собираем граф зависимоcтей руками (aka pure man DI)
void Main() {
IConfig config = ReadConfigFromSomewhere();
IDbConnectionManager dbConManager = new dbConManager(config.DbConnectionString);
IRepository1 repository1 = new MyRepository1(dbConManager);
IRepository1 repository2 = new MyRepository2(dbConManager);
IApplicationService1 appService1 = new ApplicationUseCaseService1(repository1, repository2);
IApplicationService1 appService2 = new ApplicationUseCaseService1(repository1);
// И т.д. и т.п. собираем весь граф зависимостей руками
// Затем запускаем приложение.
// В данном случае некий сервис, которые принимает запросы по сети.
using var server = new ApiServer(appService1, appService2);
server.Start();
// При этом не обязательно создавать абсолютно все объекты сразу.
// Можно сделать фабрику, которая будет делать это по требованию, e.g.
var appServiceFactory = new ApplicationServiceFactory(config);
using var server = new ApiServer(appServiceFactory);
// Внутри реализации ApiServer
private void OnRequest(string uri, object paload) {
switch(uri) {
case "useCase1": _appServiceFactory.CreateUseCase1Service().Process(payload.ParseAs<UseCase1RequestData>());
...
}
}
}
2. Используем контейнер внедрения зависимоcтей (aka DI-контейнер, IOC-контейнер)
void Main() {
IConfig config = ReadConfigFromSomewhere();
using var di = new Container();
di.AddSingleton(config);
// RepositoriesModule - эта штука, которая лежит в сборке с имплементациями и регистрирует конкретные конкретные типы
// e.g.
// ioc.AddSingleton<IDbConnectionManager>(new MySqlDbConnectionManager(config.DbConnectionString));
// ioc.AddTransient<IRepo1, Repo1Impl>();
di.Add<RepositoriesModule>(config); // Здесь можно как передать config и взять из него значения напрямую
di.Add<ApplicationServiceModule>(); // Так и позволить сервису принять IConfig напрямую и самостоятельно зачитать что ему нужно
di.AddSingleton<ApiServer>();
di.Resolve<ApiServer>().Start();
}
Re: Точка создания и инициализации конкретики приложения
Z>Получается, в начальной точке приложения должен быть какой-то супер-класс, который знает про особенности инициализации всех инфраструктурных слоев приложения.
Z>Верно?
Да. Это место так и называется "точка сборки", "корень композиции", composition root и т.п.
Z>Но тогда получается, что это "плохой" God-объект.
It depends.
Z>Как же быть?
Z>Как делать инициализацию? В какой точке? И в каком месте указанной картинки эта точка должна располагаться?
Инициализация делается в той точке где приложение стартует. Что, если подумать, логично, где еще ее делать-то?
А вот как именно делать — тут возможны варианты.
Далее я даю примеры на .NET/C#, потому что работаю в основном с этим окружением, но, думаю, в Java принципиальных отличий не будет.
1. Прямолинейный — собираем граф зависимоcтей руками (aka pure man DI)
2. Используем контейнер внедрения зависимостей (aka DI-контейнер, IOC-контейнер)
Z>Верно?
Да. Это место так и называется "точка сборки", "корень композиции", composition root и т.п.
Z>Но тогда получается, что это "плохой" God-объект.
It depends.
Z>Как же быть?
Z>Как делать инициализацию? В какой точке? И в каком месте указанной картинки эта точка должна располагаться?
Инициализация делается в той точке где приложение стартует. Что, если подумать, логично, где еще ее делать-то?
А вот как именно делать — тут возможны варианты.
Далее я даю примеры на .NET/C#, потому что работаю в основном с этим окружением, но, думаю, в Java принципиальных отличий не будет.
1. Прямолинейный — собираем граф зависимоcтей руками (aka pure man DI)
void Main() {
IConfig config = ReadConfigFromSomewhere();
IDbConnectionManager dbConManager = new dbConManager(config.DbConnectionString);
IRepository1 repository1 = new MyRepository1(dbConManager);
IRepository2 repository2 = new MyRepository2(dbConManager);
IApplicationService1 appService1 = new ApplicationUseCaseService1(repository1, repository2);
IApplicationService2 appService2 = new ApplicationUseCaseService1(repository2);
// И т.д. и т.п. собираем весь граф зависимостей руками
// Затем запускаем приложение.
// В данном случае некий сервис, которые принимает запросы по сети.
using var server = new ApiServer(appService1, appService2);
server.Start();
// При этом не обязательно создавать абсолютно все объекты сразу.
// Можно сделать фабрику, которая будет делать это по требованию, e.g.
var appServiceFactory = new ApplicationServiceFactory(config);
using var server = new ApiServer(appServiceFactory);
// Внутри реализации ApiServer
private void OnRequest(string uri, object payload) {
switch(uri) {
case "useCase1": _appServiceFactory.CreateUseCase1Service().Process(payload.ParseAs<UseCase1RequestData>());
...
}
}
}
2. Используем контейнер внедрения зависимостей (aka DI-контейнер, IOC-контейнер)
void Main() {
IConfig config = ReadConfigFromSomewhere();
using var di = new Container();
di.AddSingleton(config);
// RepositoriesModule - эта штука, которая лежит в сборке с имплементациями и регистрирует конкретные типы
// e.g.
// ioc.AddSingleton<IDbConnectionManager>(new MySqlDbConnectionManager(config.DbConnectionString));
// ioc.AddTransient<IRepo1, Repo1Impl>();
di.Add<RepositoriesModule>(config); // Здесь можно как передать config и взять конкретные значения из него для передачи в конструкторы классов
di.Add<ApplicationServiceModule>(); // Так и позволить классу принять весь IConfig в конструкторе и самостоятельно зачитать необходимое
di.AddSingleton<ApiServer>();
di.Resolve<ApiServer>().Start();
}