Локализация SharedResource и простой инжектор в ядре asp.net 2.1 - PullRequest
0 голосов
/ 07 ноября 2018

У меня есть веб-API ASP.NET в ASP.NET core 2.1, и я реализовал общий ресурс, как объяснено здесь . Это отлично работает.

Линия:

services.AddLocalization()

добавляет локализацию во встроенный контейнер IOC. (Я думаю, что это то, где волшебство происходит по крайней мере)

Теперь я добавил Simple Injector в смесь для своих собственных классов, и у меня есть класс, который я зарегистрировал как Async Scoped, который добавляется в общий ресурс (через IStringLocalizer). Тем не менее, IStringLocalizer определяется как переходный процесс, и это не совместимо с Async Scoped (так как это имеет более длинную область действия). Очевидно, я могу решить эту проблему, установив для параметра «SuppressLifestyleMismatchVerification» значение true, но это не пахнет неправильно. (в этом случае это, вероятно, не имеет значения, но с помощью этой опции я маскирую любые другие проблемы, которые могут у меня возникнуть) Есть ли способ решить эту проблему? Можно ли изменить область общего ресурса, например?

1 Ответ

0 голосов
/ 07 ноября 2018

То, что вы видите, это две вселенные сталкиваются; обе библиотеки DI имеют свое собственное несовместимое определение того, что значит быть переходным :

  • Simple Injector рассматривает компоненты с Transient образом жизни как недолговечные или краткие . Вот почему Simple Injector не позволяет вводить переходные процессы в компоненты с определенными областями; область видимости может жить гораздо дольше, чем считается краткое .
  • ASP.NET Core вообще не считает временные компоненты недолговечными . Вместо этого ожидаемый срок службы компонента Transient в .NET Core должен составлять при условии, что предполагаемый срок службы его потребителя . В документах даже говорится, что «это время жизни лучше всего подходит для легких служб без сохранения состояния».

Именно из-за этого поведения контейнер Microsoft.Extensions.DependencyInjection (MS.DI) позволяет внедрять переходные процессы как для одноэлементных, так и для ограниченных потребителей.

Я бы даже сказал, что Microsoft неправильно называет их образ жизни, потому что в действительности поведение состоит в том, чтобы иметь один экземпляр на зависимость потребителя. Microsoft, похоже, скопировала это поведение из Autofac. Autofac, однако, называет этот же стиль жизни InstancePerDependency, что является гораздо более очевидным именем, если вы спросите меня.

Странно, однако, что метод расширения AddLocalization от Microsoft регистрирует StringLocalizer<T> как переходный процесс. Это странно, потому что, кроме обернутого IStringLocalizer, StringLocalizer<T> не имеет никакого состояния. И не только это, IStringLocalizer, который он оборачивает, создается введенным IStringLocalizerFactory и, как можно ожидать, будет тем же экземпляром (что подтверждается тем фактом, что ResourceManagerStringLocalizerFactory кэширует возвращаемых экземпляров ).

Как указано выше, в MS.DI Transient означает «Я проживу так же долго, как и мой потребитель. «Это практически означает, что экземпляр StringLocalizer<T> может жить столько же, сколько и единичный, что означает: на протяжении всего приложения.

В этом отношении на самом деле действительно странно , когда команда локализации выбрала StringLocalizer<T>, чтобы вести переходный образ жизни, даже в MS.DI. Переходный процесс только означает, что создано больше экземпляров, а IStringLocalizerFactory вызывается чаще, чем требуется. Я нахожу Singleton гораздо более очевидным образом жизни для этой регистрации.

Короче говоря, я бы предложил переопределить регистрацию по умолчанию с помощью синглтона, так как в любом случае это безопасно:

services.AddLocalization();
services.AddSingleton(typeof(IStringLocalizer<>), typeof(StringLocalizer<>));
...