@romaro

Как правильно инициализировать библиотеку классов в .NET?

Есть несколько десктопных приложений, которые используют одни и те же UI-элементы, поэтому я решил вынести эти элементы в отдельную библиотеку:
ApplicationOne
ApplicationTwo
Lib.Controls


Однако часть компонентов в классах библиотеки нуждается в сервисах, которые инициализируются в корне приложения. Например, у меня есть сервис для печати этикеток. Поскольку только приложение знает, какой принтер будет использоваться, я создаю его в корне композиции и добавляю в DI-контейнер:

public class Program
    {
        [STAThread]
        public static void Main()
        {
            // Label printers setup
            var labelService = new LabelService();
            labelService.AddLabelSetup(SupportedLabels.WarehouseProductLabel, new TscPrinter("TSC TTP-225", 200));
            labelService.AddLabelSetup(SupportedLabels.OzonCargoLabel, new TscPrinter("TSC TE 200", 200, TrueTypeFont.Arial));

            var host = Host.CreateDefaultBuilder()
            .ConfigureServices(services =>
            {
                services.AddSingleton<MainWindow>();
                services.AddSingleton(labelService);
            })
            .Build();

            Lib.Controls.ApplicationHost.Init(host);

            new App(host).Run();
        }
    }


Чтобы данный сервис был доступен в окружении Lib.Controls, я реализую в этой библиотеке статический класс:
public static class ApplicationHost
    {
        static IHost? _host;

        public static void Init(IHost host)
        {
            _host = host;
        }

        internal static LabelService GetLabelService()
        {
            if (_host == null)
            {
                throw new Exception("Library Lib.Controls hasn't been initialized");
            }

            return _host.Services.GetRequiredService<LabelService>();
        }
    }


Теперь, если какому-либо компоненту потребуется напечатать этикетку, он сможет получить ее. Естественно, если библиотека была проинициализирована. То есть внутри библиотеки может быть такой код:
var labelService = ApplicationHost.GetLabelService();
IPage label = labelService.GetLabel(Print.Labels.SupportedLabels.OzonCargoLabel, placeholders);
viewModel.Page = label;
window.ShowDialog();


Является ли такая архитектура единственно возможной или у нее есть достойные альтернативы?

Пока что я вижу две проблемы:
- инициализация будет подключать библиотеки при старте приложения, т.е. никакого lazy loading.
- если библиотек несколько, каждую придется инициализировать отдельно в корне и вообще помнить о необходимости такой инициализации при создании других приложений.
  • Вопрос задан
  • 105 просмотров
Пригласить эксперта
Ответы на вопрос 1
vabka
@vabka Куратор тега .NET
Токсичный шарпист

Чтобы данный сервис был доступен в окружении Lib.Controls, я реализую в этой библиотеке статический класс:

Фатальная ошибка.


Является ли такая архитектура единственно возможной или у нее есть достойные альтернативы?

Раз у тебя уже есть DI, то следующий шаг прямо напрашивается. Создавать формы тоже при помощи DI и прокидывать все такие зависимости через конструктор.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы