#asp.net-core
#asp.net-ядро
Вопрос:
У меня есть ASP.NET Создайте базовое MVC-приложение и создайте CacheWarmerService в сервисном контейнере. В настоящее время я просто использую кэш в памяти, но мне нужно, чтобы он запускался при запуске приложения.
Однако я сомневаюсь в том, как это сделать. В моем CacheWarmerService есть некоторые службы, которые необходимо внедрить в конструктор. Могу ли я сделать это из класса Startup.cs или где это должно быть размещено?
Его необходимо запускать при каждом запуске.
Комментарии:
1. Я предполагаю, что вашим службам просто нужен материал базы данных (
DbContext
) и нет HttpContext, верно?
Ответ №1:
Вы также могли бы создать свой собственный приятный и понятный метод расширения, подобный app.UseCacheWarmer()
, из которого вы могли бы затем вызывать Startup.Configure()
:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
... logging, exceptions, etc
app.UseCacheWarmer();
app.UseStaticFiles();
app.UseMvc();
}
Внутри этого метода вы можете использовать app.ApplicationServices
для доступа к контейнеру DI (the IServiceProvider
) и получения экземпляров необходимых вам служб.
public static class CacheWarmerExtensions
{
public static void UseCacheWarmer(this IApplicationBuilder app)
{
var cacheWarmer = app.ApplicationServices.GetRequiredService<CacheWarmerService>();
cacheWarmer.WarmCache();
}
}
Комментарии:
1. Оба ответа отлично работают, но мне действительно нравится этот подход, поскольку он сохраняет загрузочный файл чистым.
2.
Use
Шаблон обычно связан с добавлением промежуточного программного обеспечения в конвейер запросов, а не с инициализацией служб.3. Вы всегда можете найти для него альтернативное название, например,
app.InitCache()
если в своем приложении вы хотите строго соблюдать соглашениеapp.UseXYZ()
только с промежуточным программным обеспечением. Суть в том, что у нас есть метод расширения, поэтому добавить службу кэша в любое веб-приложение максимально просто.
Ответ №2:
Вы можете внедрить свой сервис (и любой другой сервис) в Configure
метод Startup
.
Единственным обязательным параметром в этом методе является IApplicationBuilder
, любые другие параметры будут введены из DI, если они были настроены в ConfigureServices
.
public void Configure(IApplicationBuilder app, CacheWarmerService cache)
{
cache.Initialize(); // or whatever you call it
...
app.UseMvc();
}
Комментарии:
1. В asp.net ядро 2.1 вы больше не можете вводить параметры в метод Configure
2. Должно быть, я сделал что-то неправильно изначально, так как я получал исключение, и теперь я просто попробовал это снова, это работает так, как вы описали. Извините за любую путаницу
3. Я думаю, что они должны быть зарегистрированы с одноэлементной пожизненной областью, чтобы это работало.
4. @fml Кэш работает, да, но если вам нужны службы с ограниченной областью для заполнения кэша, вы можете просто создать контекст области с помощью этого learn.microsoft.com/en-us/dotnet/api/… Не уверен, на что это вы намекали или нет, но просто подумал, что сделаю это на всякий случай
Ответ №3:
Если кто-то использует метод Дэниелса и использует службы с ограниченной областью действия, такие как EF data context внутри службы cachewarm, вы получите сообщение об ошибке ниже.
'Cannot resolve 'ICacheWarmerService' from root provider because it requires scoped service 'dbContext'.'
Для этого вы можете создать область видимости и использовать свой кэшированный метод.
public static void UseCacheWarmer(this IApplicationBuilder app)
{
using (var serviceScope = app.ApplicationServices.CreateScope())
{
var cacheWarmer = serviceScope.ServiceProvider.GetService<ICacheWarmerService>();
cacheWarmer.WarmCache();
}
//// var cacheWarmer = app.ApplicationServices.GetRequiredService<ICacheWarmerService>();
//// cacheWarmer.WarmCache();
}