Альтернатива условной компиляции в C # для инициализации базы данных - PullRequest
0 голосов
/ 17 декабря 2018

Я исследую альтернативную реализацию для инициализации базы данных, которая не зависит от #if #elif ..... (не работает для кода .Net в известной проблеме VS2017), чтобы выбрать инициализаторы базы данных для конкретного клиента.Один из подходов, который представляется целесообразным как для среды разработки, так и для сред CI / CD, заключается в следующем:

  • Создание интерфейса инициализатора базы данных.
  • Создание проекта сборки ac # для каждого сайта, содержащего экземпляринтерфейса выше.
  • Настройте уровень базы данных решения для загрузки сборки инициализатора базы данных во время выполнения.
  • Напишите сценарий powershell со строковым параметром 'siteName', создающий решение (на основеПараметр siteName) переименовывает инициализатор базы данных сайта, чтобы вышеуказанный шаг мог загрузить сборку во время выполнения.

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

Это тип DI init, который я хочу изменить, удалить зависимость от #if ....

private void DatabaseInitialiseDefinitions(ContainerBuilder builder)
{
        #if site1
                    builder.RegisterType<site1ResourceIdentityDefinitions>()
                        .As<IResourceIdentityDefinition>()
                        .SingleInstance();
                    builder.RegisterType<site1UserDefinitions>()
                        .As<IUserDefinitions>()
                    .SingleInstance();
        #elif site2
                    builder.RegisterType<site2ResourceIdentityDefinition>()
                        .As<IResourceIdentityDefinition>()
                        .SingleInstance();
                    builder.RegisterType<site2UserDefinitions>()
                        .As<IUserDefinitions>()
                        .SingleInstance();
        #elif site3
                    builder.RegisterType<site3ResourceIdentityDefinition>()
                        .As<IResourceIdentityDefinition>()
                        .SingleInstance();
                    builder.RegisterType<site3UserDefinitions>()
                        .As<IUserDefinitions>()
                        .SingleInstance();
}

1 Ответ

0 голосов
/ 17 декабря 2018

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

Если это более специфичные для арендатора версии, делать это напрямую с DI намного проще, чем время сборки.Даже если вы просто зарегистрируете дополнительные реализации арендатора, контейнер DI, такой как Autofac, извлечет последнюю соответствующую регистрацию, если вы не запросите IEnumerable услуг.Если бы это был я, я бы использовал Dependency Injection и рассматривал приложение как мультитенантное.Возможно, каждое приложение работает изолированно, но код по-прежнему мультитенантен.

Если бы у вас было много регистраций, я бы использовал дочерние контейнеры для хранения регистраций, специфичных для каждого арендатора.

Если вы используете Autofac, то это расширение будет работать - https://github.com/autofac/Autofac.AspNetCore.Multitenant или https://github.com/autofac/Autofac.Multitenant (если не .Net Core)

Мы использовали его с несколькими стратегиями дляопределить владельца - проще всего был параметр конфигурации в app.config, который сообщал ему, от какого клиента он работает.Текущий основан на имени хоста, поэтому все клиенты работают под одним приложением.Если бы это было локальное приложение, я бы ожидал настройки в конфигурации, которые бы указывали на то, какой арендатор будет.

...